Opened 8 years ago
Closed 8 years ago
#27709 closed Bug (fixed)
ContentTypes.objects.get_for_models returns inconsistent results for proxy models
Reported by: | Peter Inglesby | Owned by: | nobody |
---|---|---|---|
Component: | contrib.contenttypes | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If UserProxy
is a proxy model, then the result of calling ContentTypes.objects.get_for_models(UserProxy)
depends on whether the content types cache is empty:
>>> ContentType.objects.clear_cache() >>> ContentType.objects.get_for_models(UserProxy) {<class 'django.contrib.auth.models.User'>: <ContentType: user>} >>> ContentType.objects.get_for_models(UserProxy) {<class 'gallery.models.UserProxy'>: <ContentType: user>}
In particular, on the first call to get_for_models
, the key in the results dictionary is the concrete model, while on subsequent calls it is the proxy model.
I believe the correct behaviour is to return the proxy model as the key.
I have two proposed fixes, each with pros and cons. Should I open two separate pull requests?
Change History (6)
comment:1 by , 8 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Type: | Uncategorized → Bug |
Version: | 1.10 → master |
comment:2 by , 8 years ago
That fix doesn't work, and breaks an existing test.
I've submitted a pull request that changes get_for_models()
to use get_for_model()
. This simplifies the code a lot, but means there will be one database query for each model that's not in the cache, rather than at most one database query per call to get_for_models()
. Given that calls to get_for_model()
are cached, I believe this is acceptable.
I have an alternative fix that preserves the existing behaviour with respect to the number of database queries, but makes the code slightly harder to follow.
comment:3 by , 8 years ago
Has patch: | set |
---|
comment:5 by , 8 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
The proxy model should only be returned as a key if for_concrete_models=False is specified.
A single one changing this line to
results[opts.concrete_model if for_concrete_models else model] = ct
and adding tests to this module should do.