複数レベルの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)

そして、クエリセットを取得したいと思います。プリフェッチを確実に実行したい場合は、次のようにしますPublisherPublisher.object.all()

Publisher.objects.all().prefetch_related('book_set')`

私の質問は次のとおりです:

  1. このプリフェッチを を使用して行う方法はありますかselect_related、それとも を使用する必要がありますかprefetch_related?
  2. をプリフェッチする方法はありますかpage_set? これは機能しません:

Publisher.objects.all().prefetch_related('book_set', 'book_set_page_set')

ベストアンサー1

Django 1.7 以降では、django.db.models.Prefetchクラスのインスタンスを の引数として使用できます.prefetch_relatedPrefetchオブジェクト コンストラクターには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

おすすめ記事