为什么 Django 的 related_model 属性 返回字符串而不是模型实例?
Why Django's related_model property is returning string instead of Model instance?
我有一些奇怪的行为,至少对我来说是这样,这导致我的项目出现一些错误。
我正在使用 Django 1.9 和第三方 django 包 (django-jet),它在 Django 管理中使用了 field.related_model
属性,有时它会失败,因为它期望 field.related_model
returns 一个模型实例,我的一些模型正在返回模型名称。
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
我尝试过的事情:
- 如果 Django 的 related_model 是 @属性 而不是 @cached_property 它可以工作和 returns 模型实例。
- 如果我在导致错误的行中调用
field.remote_field.model
而不是 field.related_model
并且 returns 模型实例。
拜托,你有什么想法吗?我可以解决这个问题,但我想知道为什么会出现这种情况。
提前致谢!
我认为这里出现问题是因为 jet 试图在 RelatedFieldAjaxListFilter.field_choices()
方法中使用 related_model
,并且这可能在所有应用程序加载之前执行。如果我没理解错的话,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()
可能会做类似的事情。
我有一些奇怪的行为,至少对我来说是这样,这导致我的项目出现一些错误。
我正在使用 Django 1.9 和第三方 django 包 (django-jet),它在 Django 管理中使用了 field.related_model
属性,有时它会失败,因为它期望 field.related_model
returns 一个模型实例,我的一些模型正在返回模型名称。
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
我尝试过的事情:
- 如果 Django 的 related_model 是 @属性 而不是 @cached_property 它可以工作和 returns 模型实例。
- 如果我在导致错误的行中调用
field.remote_field.model
而不是field.related_model
并且 returns 模型实例。
拜托,你有什么想法吗?我可以解决这个问题,但我想知道为什么会出现这种情况。
提前致谢!
我认为这里出现问题是因为 jet 试图在 RelatedFieldAjaxListFilter.field_choices()
方法中使用 related_model
,并且这可能在所有应用程序加载之前执行。如果我没理解错的话,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()
可能会做类似的事情。