为了简单起见,假设这些是 django 模型:
class A():
a = manytomany('B')
class B():
b = charfield()
z = foreignkey('C')
class C():
c = charfield()
我们可以做这样的事情来获取z
也:
foo = A.objects.get(pk = 1).prefetch_related('a').select_related('a__z')
为了简单起见,假设这些是 django 模型:
class A():
a = manytomany('B')
class B():
b = charfield()
z = foreignkey('C')
class C():
c = charfield()
我们可以做这样的事情来获取z
也:
foo = A.objects.get(pk = 1).prefetch_related('a').select_related('a__z')
这个答案对于 1.7 之前的 Django 版本是正确的。它产生三个查询:首先,获取 的实例A
,然后获取其相关的实例,B
最后获取与第二个查询中获取的实例C
相关的实例。B
在 Django 1.7 之前,这是您能做的最好的事情,尽管理论上第二个查询可以选择所有B
对象以及C
通过z
ForeignKey
.
从 Django 1.7 开始,有一个更高级的django.db.models.Prefetch
类可以让你做到这一点。您可以自Prefetch
定义用于预取相关对象的查询集,如下所示:
foo = A.objects.prefetch_related(
Prefetch('a', queryset=B.objects.select_related('z'))
).get(pk=1)
这只会产生两个查询(而不是使用 时的三个prefetch_related('a__z')
),并让数据库处理第二个连接,理论上这应该会带来更好的性能。
您只需要一个prefetch_related
电话:
foo = A.objects.prefetch_related('a__z').get(pk=1)
这将预取两个表。在 Django 1.7+ 中,您可以通过使用Prefetch
对象来提高性能,如koniiiik 的回答。