我有一些奇怪的行为,至少对我而言,这会导致我的项目中出现一些错误。
我正在使用Django 1.9和第三方django包(django-jet),它在Django admin中使用field.related_model
属性,有时会失败,因为它期望field.related_model
返回一个模型实例并且我的一些模型正在返回模型名称。
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
我尝试的事情:
field.remote_field.model
而不是field.related_model
,则会返回模型实例。拜托,你有什么想法吗?我可以解决这个问题,但我想知道为什么会出现这种情况。
提前致谢!
答案 0 :(得分:2)
我认为这里出现的问题是因为jet试图在related_model
方法中使用RelatedFieldAjaxListFilter.field_choices()
,这可能会在所有应用程序加载之前执行。如果我理解正确,related_model
值最初是一个字符串,在模型初始化过程中用模型对象替换。如果您在应用程序全部加载之前尝试获取该值,则可能会获得字符串或对象,具体取决于加载模型的顺序。并且,由于它是一个缓存属性,在该阶段获取字符串值将导致缓存字符串值。例如,请参阅django.db.models.options
,
# The mechanism for getting at the related model is slightly odd -
# ideally, we'd just ask for field.related_model. However, related_model
# is a cached property, and all the models haven't been loaded yet, so
# we need to make sure we don't cache a string reference.
通过使related_name
成为未缓存的属性,可以避免该问题。
在django.contrib.admin.filters.RelatedFieldListFilter
代码中,他们不使用related_model
来获取模型对象,而是使用实用程序函数django.contrib.admin.utils.get_model_from_relation()
。 RelatedFieldAjaxListFilter.field_choices()
可能应该做类似的事情。