2016-03-02 49 views
7

我有一些奇怪的行为,至少对我而言,这导致了我的项目中的一些错误。为什么Django的related_model属性返回字符串而不是Model实例?

我使用Django 1.9,这让在Django管理field.related_model财产的使用,有时它,因为它预计field.related_model回报模型实例和我的一些车型将返回型号名称失败第三方Django的包(django-jet) 。

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的行中导致错误生效并返回模型实例。

请问,你有什么想法吗?我可以制定解决方法,但我想知道为什么会出现这种情况。

在此先感谢!

回答

2

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

相关问题