[英]In django, is there a way to directly annotate a query with a related object in single query?
考慮這個查詢:
query = Novel.objects.< ...some filtering... >.annotate(
latest_chapter_id=Max("volume__chapter__id")
)
實際上,我需要用其最新的Chapter
對象注釋每個Novel
,因此在此查詢之后,我必須執行另一個查詢以通過注釋 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 對象。
希望這會有所幫助,任何像我一樣后來看起來像的人。
可以使用 Django 3.2+
使用django.db.models.functions.JSONObject
(在 Django 3.2 中添加)來組合多個字段(在這個例子中,我正在獲取最新的對象,但是如果你可以獲取LIMIT 1)
就可以獲取任意對象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]
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.