Django4.0 聚合-在QuerySet中的每一個條目生成聚合

2022-03-16 17:34 更新

生成值的匯總的另一個辦法是為 ?QuerySet ?的每一個對象生成獨(dú)立匯總。比如,如果你想檢索書籍列表,你可能想知道每一本書有多少作者。每一本書與作者有多對多的關(guān)系;我們想在 ?QuerySet ?中為每一本書總結(jié)這個關(guān)系。

使用 ?annotate()? 子句可以生成每一個對象的匯總。當(dāng)指定 ?annotate()? 子句,?QuerySet ?中的每一個對象將對指定值進(jìn)行匯總。

這些語法與用于 ?aggregate()? 子句的語法相同。 annotate() 的每個參數(shù)都描述了一個要計算的聚合。 例如,用作者數(shù)量注釋書籍:

# Build an annotated queryset
>>> from django.db.models import Count
>>> q = Book.objects.annotate(Count('authors'))
# Interrogate the first object in the queryset
>>> q[0]
<Book: The Definitive Guide to Django>
>>> q[0].authors__count
2
# Interrogate the second object in the queryset
>>> q[1]
<Book: Practical Django Projects>
>>> q[1].authors__count
1

與 ?aggregate()? 一樣,注解的名稱是根據(jù)聚合函數(shù)和被聚合的字段名自動生成的。當(dāng)你在指定注解的時候,你可以通過提供一個別名重寫這個默認(rèn)名:

>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1

與 ?aggregate()? 不同的是,?annotate()? 不是終端子句。?annotate()? 子句的輸出就是 ?QuerySet?;這個 ?QuerySet ?被其他 ?QuerySet ?操作進(jìn)行修改,包括 ?filter()?, ?order_by()? ,甚至可以對 ?annotate()? 進(jìn)行額外調(diào)用。

組合多個聚合

將多個聚合與? annotate() ?組合會產(chǎn)生錯誤的結(jié)果,因?yàn)槭褂玫氖沁B接而不是子查詢:

>>> book = Book.objects.first()
>>> book.authors.count()
2
>>> book.store_set.count()
3
>>> q = Book.objects.annotate(Count('authors'), Count('store'))
>>> q[0].authors__count
6
>>> q[0].store__count
6

對大部分聚合來說,沒辦法避免這個問題,但是,?Count ?聚合可以使用 ?distinct ?參數(shù)來避免:

>>> q = Book.objects.annotate(Count('authors', distinct=True), Count('store', distinct=True))
>>> q[0].authors__count
2
>>> q[0].store__count
3


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號