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 do
Publisher.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
    或reverse
    ForeignKey
    字段需要它

  • 您是否尝试过使用两个下划线进行多级预取?如下所示:
    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'))
    我相信这将是第二个版本。这是一个非常出色的答案,可以让您节省大量数据库流量。我不明白为什么这个答案没有得到太多的关注