prefetch_related为多层次
问题描述:
如果我的模式是这样的:prefetch_related为多层次
class Publisher(models.Model):
pass
class Book(models.Model):
publisher = models.ForeignKey(Publisher)
class Page(models.Model):
book = models.ForeignKey(Book)
,我想获得Publisher
的查询集我做Publisher.object.all()
。 如果再要确保预取我可以这样做:
Publisher.objects.all().prefetch_related('book_set')`
我的问题是:
- 有没有一种方法使用
select_related
或 我必须用prefetch_related
做这个预取? - 有没有办法预取
page_set
?这不起作用:
Publisher.objects.all().prefetch_related('book_set', 'book_set_page_set')
答
不,你不能反向关系使用
select_related
。select_related
执行SQL连接,因此主要查询集中的单个记录需要在相关表(ForeignKey
或OneToOne
字段)中恰好引用一个记录。prefetch_related
实际上完成了一个完全独立的第二个查询,缓存结果,然后将它“连接”到python的查询集中。所以需要ManyToMany
或反向ForeignKey
字段。您是否尝试了两次下划线来执行多级预取?像这样:
Publisher.objects.all().prefetch_related('book_set', 'book_set__page_set')
答
由于Django的1.7,django.db.models.Prefetch
类的实例可以用作的.prefetch_related
参数。 Prefetch
对象构造具有queryset
论点,即允许指定这样的嵌套多层次预取:
Project.objects.filter(
is_main_section=True
).select_related(
'project_group'
).prefetch_related(
Prefetch(
'project_group__project_set',
queryset=Project.objects.prefetch_related(
Prefetch(
'projectmember_set',
to_attr='projectmember_list'
)
),
to_attr='project_list'
)
)
因为我使用ListQuerySet
处理预取结果(过滤器/顺序):存储到属性与_list
后缀。
2.双下划线的作品。 – 2014-11-25 02:18:08
1.如果'Page'具有'OneToOne'字段到'TextContent',它会是:'... prefetch_related('book_set__page_set__text_contents')'或'... select_related('book_set__page_set__text_contents')' – 2014-11-25 02:20:01
我相信它会成为第二个版本。 – jproffitt 2014-11-25 02:25:12