In django, is there a way to directly annotate a query with a related object in single query?

前端 未结 3 577
南旧
南旧 2021-02-05 18:02

Consider this query:

query = Novel.objects.< ...some filtering... >.annotate(
    latest_chapter_id=Max(\"volume__chapter__id\")
)

Actual

3条回答
  •  悲哀的现实
    2021-02-05 18:19

    Yes, using Subqueries, docs: https://docs.djangoproject.com/en/3.0/ref/models/expressions/#subquery-expressions

    latest_chapters = Chapter.objects.filter(novel = OuterRef("pk"))\
        .order_by("chapter_order")
    
    novels_with_chapter = Novel.objects.annotate(
        latest_chapter = Subquery(latest_chapters.values("chapter")[:1]))
    

    Tested on Django 3.0

    The subquery creates a select statement inside the select statement for the novels, then adds this as an annotation. This means you only hit the database once.

    I also prefer this to Rune's answer as it actually annotates a Novel object.

    Hope this helps, anyone who came looking like much later like I did.

提交回复
热议问题