在django中,有没有办法在单个查询中直接用相关对象注释查询?

时间:2012-08-27 00:52:40

标签: python django annotate

考虑这个问题:

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

实际上我需要的是用最新的Novel对象注释每个Chapter,因此在此查询之后我必须执行另一个查询以通过带注释的ID选择实际对象。 IMO这很难看。有没有办法将它们组合成一个查询?

3 个答案:

答案 0 :(得分:20)

是的,这是可能的。

要获取一个包含所有章节的查询集,这些章节是小说中的最后一章,只需执行:

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上测试。

答案 1 :(得分:3)

不,不可能将它们组合成单个查询。

您可以阅读以下blog post以找到两种解决方法。

答案 2 :(得分:0)

是,使用子查询,文档: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语句,然后将其添加为注释。这意味着您只打过一次数据库。

我也更喜欢符文的答案,因为它实际上注释了一个Novel对象。

希望这会有所帮助,像我以后来的很多人。