考虑这个查询:
query = Novel.objects.< ...some filtering... >.annotate(
latest_chapter_id=Max("volume__chapter__id")
)
实际上,我需要Novel
用其最新Chapter
对象注释每个对象,因此在此查询之后,我必须执行另一个查询以通过注释 ID 选择实际对象。IMO 这很丑陋。有没有办法将它们组合成一个查询?
考虑这个查询:
query = Novel.objects.< ...some filtering... >.annotate(
latest_chapter_id=Max("volume__chapter__id")
)
实际上,我需要Novel
用其最新Chapter
对象注释每个对象,因此在此查询之后,我必须执行另一个查询以通过注释 ID 选择实际对象。IMO 这很丑陋。有没有办法将它们组合成一个查询?
是的,这是可能的。
要获得一个包含小说中最后一章的所有章节的查询集,只需执行以下操作:
from django.db.models.expressions import F
from django.db.models.aggregates import Max
Chapters.objects.annotate(last_chapter_pk=Max('novel__chapter__pk')
).filter(pk=F('last_chapter_pk'))
在 Django 1.7 上测试。
不,不可能将它们组合成一个查询。
您可以阅读以下博客文章以找到两种解决方法。
是的,使用子查询,文档: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]))
在 Django 3.0 上测试
子查询在小说的 select 语句中创建一个 select 语句,然后将其添加为注释。这意味着您只需访问数据库一次。
我也更喜欢 Rune 的答案,因为它实际上注释了 Novel 对象。
希望这会有所帮助,任何像我一样晚来的人。