【问题标题】:Django model inheritance and select_relatedDjango模型继承和select_related
【发布时间】:2015-07-25 16:22:40
【问题描述】:

我在模型中有以下内容,当我使用 select_related 和模型继承时遇到了奇怪的行为:

型号:

class A(models.Model):
    field_fk = models.ForeignKey('C')

class B(A):
    fields_b = models.CharField(max_length=255)

class C(models.Model):
    field_c = models.CharField(max_length=255)

所以 A 有一个指向 C 的外键,而 B 继承自 A。 现在我想查询 A 向下转换为 B 并读取与 C 的关系。为了最小化 sql 查询,我使用select_related

obj = A.objects.select_related('b', 'field_fk).first()
obj = obj.b          
print(obj.field_fk)  # this prints "C object"

因为我使用select_related,所以应该只得到一个查询。但不知何故,信息在向下转换期间丢失了,我开始进行 sql 查询:

SELECT ••• FROM "base_a" INNER JOIN "base_c" ON 
      ( "base_a"."field_fk_id" = "base_c"."id" ) LEFT OUTER JOIN "base_b" ON 
      ( "base_a"."id" = "base_b"."a_ptr_id" ) ORDER BY "base_a"."id" ASC LIMIT 1

SELECT ••• FROM "base_c" WHERE "base_c"."id" = 1

所以在第一个查询中看起来不错。但令我惊讶的是,我收到了第二个查询。 这是 django 的 ORM 中的错误还是我做错了什么?

【问题讨论】:

    标签: django django-models django-orm django-inheritance


    【解决方案1】:

    您重新分配 obj 变量,所以您基本上要做的是:

    print(obj.b.field_fk)

    虽然.b.field_fk 未被选为相关对象。因此,要么将其添加到 select_related 中,要么在重新分配 obj 变量之前重用预取的对象

    【讨论】:

    • 你是对的,但我仍然认为这是一个错误。这种将 select_related 与模型继承一起使用的方式是无用的。我在 django-project 开了一张票。我希望这将很快得到解决:code.djangoproject.com/ticket/25173
    【解决方案2】:

    如前所述,我在 django-project 提交了一张票。 https://code.djangoproject.com/ticket/25173

    这现在被认为是一个错误,并有望很快得到修复。

    建议的解决方法是:

     obj = obj.b        
     print (obj.a_ptr.field_fk)
    

    【讨论】:

      猜你喜欢
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多