13

考虑这个查询:

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

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

4

3 回答 3

32

是的,这是可能的。

要获得一个包含小说中最后一章的所有章节的查询集,只需执行以下操作:

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

于 2015-01-14T13:10:41.383 回答
3

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

您可以阅读以下博客文章以找到两种解决方法。

于 2012-08-27T01:26:19.310 回答
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 语句,然后将其添加为注释。这意味着您只需访问数据库一次。

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

希望这会有所帮助,任何像我一样晚来的人。

于 2020-06-04T15:35:46.333 回答