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

2022-03-16 17:34 更新

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

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

這些語法與用于 ?aggregate()? 子句的語法相同。 annotate() 的每個(gè)參數(shù)都描述了一個(gè)要計(jì)算的聚合。 例如,用作者數(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)生成的。當(dāng)你在指定注解的時(shí)候,你可以通過提供一個(gè)別名重寫這個(gè)默認(rèn)名:

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

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

組合多個(gè)聚合

將多個(gè)聚合與? annotate() ?組合會(huì)產(chǎn)生錯(cuò)誤的結(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

對(duì)大部分聚合來說,沒辦法避免這個(gè)問題,但是,?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)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)