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

SAP*_*chu 10 python django annotate django-orm

考虑这个查询:

query = Novel.objects.< ...some filtering... >.annotate(
    latest_chapter_id=Max("volume__chapter__id")
)
Run Code Online (Sandbox Code Playgroud)

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

Run*_*ard 22

是的,这是可能的.

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

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'))
Run Code Online (Sandbox Code Playgroud)

在Django 1.7上测试过.


şua*_*mez 13

Django 3.2+ 可以实现

利用django.db.models.functions.JSONObject(在 Django 3.2 中添加)组合多个字段(在本示例中,我正在获取最新的对象,但是只要您可以生成对象,就可以获取任意LIMIT 1)对象):

MainModel.objects.annotate(
    last_object=RelatedModel.objects.filter(mainmodel=OuterRef("pk"))
    .order_by("-date_created")
    .values(
        data=JSONObject(
            id="id", body="body", date_created="date_created"
        )
    )[:1]
)
Run Code Online (Sandbox Code Playgroud)


thi*_*nom 5

不,不可能将它们合并到单个查询中。

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

  • rune-kaagaard 的答案现在更好了。 (4认同)
  • 链接的帖子建议在查询中使用 extra() 。从 Django 1.8 开始,不推荐使用 extra(),并且已弃用。 (2认同)