如果我的模型看起来像:
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'
)
)
它存储在带有_list
后缀的属性中,因为我使用ListQuerySet
来处理预取结果(过滤器/顺序)。