【问题标题】:Why Django's related_model property is returning string instead of Model instance?为什么 Django 的related_model 属性返回字符串而不是模型实例?
【发布时间】:2016-06-15 05:03:24
【问题描述】:

我有一些奇怪的行为,至少对我来说是这样,这导致我的项目出现了一些错误。

我正在使用 Django 1.9 和第三方 django 包 (django-jet),它在 Django 管理中使用 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

我尝试过的事情:

  • 如果 Django 的 related_model 是 @property 而不是 @cached_property,它会工作并返回模型实例。
  • 如果我在导致错误的行中调用 field.remote_field.model 而不是 field.related_model,它会起作用并返回模型实例。

请问,你有什么想法吗?我可以解决这个问题,但我想知道为什么会出现这种行为。

提前致谢!

【问题讨论】:

    标签: python django django-admin django-jet


    【解决方案1】:

    我认为这里的问题出现是因为 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() 应该做类似的事情。

    【讨论】:

      猜你喜欢
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2011-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多