![](/img/trans.png)
[英]Django: How to annotate M2M or OneToMany fields using a SubQuery?
[英]Django - Annotate multiple fields from a Subquery
我正在處理一個 Django 項目,在該項目上我有一個“A”對象( A.objects.all()
)的查詢集,我需要從“B”對象的子查詢中注釋多個字段。 問題是 annotate 方法只能處理每個參數的一種字段類型(DecimalField、CharField 等),因此,為了注釋多個字段,我必須使用類似的方法:
A.objects.all().annotate(b_id =Subquery(B_queryset.values('id')[:1],
b_name =Subquery(B_queryset.values('name')[:1],
b_other_field =Subquery(B_queryset.values('other_field')[:1],
... )
這是非常低效的,因為它為我要注釋的每個字段在最終 SQL 上創建了一個新的子查詢/子選擇。 我想在它的 values() 參數上使用具有多個字段的相同子選擇,並將它們全部注釋在 A 的查詢集上。 我想使用這樣的東西:
b_subquery = Subquery(B_queryset.values('id', 'name', 'other_field', ...)[:1])
A.objects.all().annotate(b=b_subquery)
但是當我嘗試這樣做(並訪問第一個元素A.objects.all().annotate(b=b_subquery)[0]
)時,它引發了一個異常:
{FieldError}Expression contains mixed types. You must set output_field.
如果我設置Subquery(B_quer...[:1], output_field=ForeignKey(B, models.DO_NOTHING))
,我會得到一個數據庫異常:
{ProgrammingError}subquery must return only one column
簡而言之,整個問題是我有多個“屬於”A 的 B,所以我需要使用子查詢,對於A.objects.all()
每個 A,選擇一個特定的 B 並將其附加到A,使用 OuterRefs 和一些過濾器(我只想要 B 的幾個字段),這對我來說是一個微不足道的問題。
提前感謝您的任何幫助!
我在這種情況下所做的是使用與預取相關的
a_qs = A.objects.all().prefetch_related(
models.Prefetch('b_set',
# NOTE: no need to filter with OuterRef (it wont work anyway)
# Django automatically filter and matches B objects to A
queryset=B_queryset,
to_attr='b_records'
)
)
現在a.b_records
將是一個包含a's
相關b
對象的列表。 根據您過濾B_queryset
此列表可能僅限於 1 個對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.