I have some strange behaviour, at least for me, that is causing me some bugs in my project.
I am using Django 1.9 and a third party django package (django-jet) that makes usage of field.related_model property in Django admin and sometimes it fails because it expects field.related_model returns a model instance and for some of my models is returning the model name.
This is the property defined in Django code:
@cached_property
def related_model(self):
# Can't cache this property until all the models are loaded.
apps.check_models_ready()
return self.remote_field.model
Things that I tried:
- If Django's related_model is a @property instead a @cached_property it works and returns the model instance.
- If I call
field.remote_field.modelinstead offield.related_modelin the line that is causing the bug it works and returns the model instance.
Please, do you have any idea? I can make the workaround but I would like to know why this behaviour.
Thanks in advance!
I think the problem here arises because jet is trying to use
related_modelin theRelatedFieldAjaxListFilter.field_choices()method, and this may executed before all apps have been loaded. If I understand correctly, therelated_modelvalue is initially a string, which is replaced with a model object in the course of model initialization. If you try to get that value before the apps have all loaded, you may get either a string or an object, depending on the order in which the models are loaded. And, since it's a cached property, getting a string value at that stage would cause the string value to be cached. See, for example, the comment indjango.db.models.options,By making
related_namean uncached property, you avoid that issue.In the
django.contrib.admin.filters.RelatedFieldListFiltercode, they do NOT userelated_modelto get the model object, but instead use a utility function,django.contrib.admin.utils.get_model_from_relation(). TheRelatedFieldAjaxListFilter.field_choices()should probably be doing something similar.