Django 与多个级别相关的预取\u
如果我的模型看起来像:Django 与多个级别相关的预取\u,django,django-queryset,django-orm,Django,Django Queryset,Django Orm,如果我的模型看起来像: class Publisher(models.Model): pass class Book(models.Model): publisher = models.ForeignKey(Publisher) class Page(models.Model): book = models.ForeignKey(Book) 我想获得PublisherI doPublisher.object.all()的查询集。 如果要确保预回迁,我可以执行以下操作
class Publisher(models.Model):
pass
class Book(models.Model):
publisher = models.ForeignKey(Publisher)
class Page(models.Model):
book = models.ForeignKey(Book)
我想获得Publisher
I doPublisher.object.all()
的查询集。
如果要确保预回迁,我可以执行以下操作:
Publisher.objects.all().prefetch_related('book_set')`
我的问题是:
select\u related
或
我必须使用预取\u相关的
页面设置
?这不起作用:Publisher.objects.all().prefetch\u相关('book\u set'、'book\u set\u page\u set')
选择相关的进行反向关系select\u related
执行SQL联接,因此主查询集中的单个记录需要引用相关表中的一条记录(ForeignKey
或OneToOne
字段)prefetch\u related
实际上执行完全独立的第二次查询,缓存结果,然后将其“连接”到python中的查询集。因此,manytomy
或reverseForeignKey
字段需要它
Publisher.objects.all().prefetch\u related('book\u set'、'book\u set\u page\u set')
自Django 1.7以来,
Django.db.models.Prefetch
类的实例可以用作与.Prefetch\u相关的
的参数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'
)
)
它存储在带有
\u list
后缀的属性中,因为我使用ListQuerySet
来处理预取结果(筛选/排序)。1。如果Page
有一个OneToOne
字段来TextContent
,它会是:…预取相关('book\u set\u Page\u set\u text\u contents')
还是…选择相关('book\u set\u Page\u set\u text\u contents'))
我相信这将是第二个版本。这是一个非常出色的答案,可以让您节省大量数据库流量。我不明白为什么这个答案没有得到太多的关注