Django 模型继承和 select_related
Django model inheritance and select_related
我在模型中有以下内容,当我使用 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 中的错误还是我做错了什么?
你重新分配 obj
变量,所以你基本上做的是:
print(obj.b.field_fk)
而 .b.field_fk
未被选为相关对象。因此,要么将其添加到 select_related
中,要么在重新分配 obj
变量
之前重复使用预取对象
如前所述,我在 django-project 提交了一张票。
https://code.djangoproject.com/ticket/25173
这现在被认为是一个错误,希望很快得到修复。
建议的解决方法是:
obj = obj.b
print (obj.a_ptr.field_fk)
我在模型中有以下内容,当我使用 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 中的错误还是我做错了什么?
你重新分配 obj
变量,所以你基本上做的是:
print(obj.b.field_fk)
而 .b.field_fk
未被选为相关对象。因此,要么将其添加到 select_related
中,要么在重新分配 obj
变量
如前所述,我在 django-project 提交了一张票。 https://code.djangoproject.com/ticket/25173
这现在被认为是一个错误,希望很快得到修复。
建议的解决方法是:
obj = obj.b
print (obj.a_ptr.field_fk)