#20442 closed Bug (fixed)
Stale ContentType objects cause a NoneType error in get_for_id
Description ¶
When content types are stale an error occurs when using ContentType.objects.get_for_id()
:
Traceback (most recent call last): ... File "/Users/diederik/Sites/webapps/django/django/contrib/contenttypes/tests.py", line 280, in <lambda> test = ContentType.objects.get_for_id(ct.pk) File "/Users/diederik/Sites/webapps/django/django/contrib/contenttypes/models.py", line 107, in get_for_id self._add_to_cache(self.db, ct) File "/Users/diederik/Sites/webapps/django/django/contrib/contenttypes/models.py", line 122, in _add_to_cache key = (model._meta.app_label, model._meta.model_name) AttributeError: 'NoneType' object has no attribute '_meta'
The object can still be fetched, but ct.model_class()
returns None
which causes the _add_to_cache
function to operate on a NoneType.
Change History (4)
comment:1 by , 12 years ago
Status: | new → assigned |
---|---|
Type: | Uncategorized → Bug |
comment:2 by , 12 years ago
Has patch: | set |
---|
When evaluating the solutions with my local projects, it turns out that option nr1 (return the content type) is the best solution.
The get_for_id()
returns the ContentType
object as promised, and like any other operation (e.g. ContentType.objects.all()
), the caller would have to check for ct.model_class() is None
.
Pull request: https://github.com/django/django/pull/1130
comment:3 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:4 by , 11 years ago
Version: | 1.4 → 1.6 |
---|
I was thinking about solving this in a few possible ways:
_add_to_cache
use(ct.app_label, ct.model)
as key instead of the model object. I think they are always identical, so this would allow caching the stale content type. Nothing changes for calling code, they still need to check whetherct.model_class()
returnsNone
as it explicitly does already.StaleContentTypeError
inget_for_id()
. This would require updating code everywhere else too.ContentType.DoesNotExist
. This gives consistent output fromContentType.objects.get_for_id()
I don't like it as will leak out the inconsistency elsewhere.My preference goes to the first option.