Django4.0 聚合-連接(Joins)和聚合

2022-03-16 17:34 更新

到目前為止,我們已經(jīng)處理了被查詢模型字段的聚合。然而,有時候想聚合的值屬于你正在查詢模型的關(guān)聯(lián)模型。

當(dāng)在聚合函數(shù)中指定要聚合的字段時,Django 將允許您使用與在過濾器中引用相關(guān)字段時使用的相同的雙下劃線表示法。 然后,Django 將處理檢索和聚合相關(guān)值所需的任何表連接。

比如,要尋找每個書店提供的書籍價格區(qū)間,你可以使用這個注解(annotation):

>>> from django.db.models import Max, Min
>>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))

這告訴 Django 去檢索 ?Store ?模型,連接(通過多對多關(guān)系) ?Book ?模型,并且聚合書籍模型的價格字段來獲取最大最小值。
相同規(guī)則應(yīng)用于 ?aggregate()? 從句。如果你想知道任何店鋪正在銷售的任何書籍的最低最高價,你可以使用這個聚合:

>>> Store.objects.aggregate(min_price=Min('books__price'), max_price=Max('books__price'))

?Join ?鏈可以根據(jù)你的需求盡可能深。比如,要提取所出售的書籍中最年輕的作者年齡,你可以寫這樣的查詢:

>>> Store.objects.aggregate(youngest_age=Min('books__authors__age'))

反向關(guān)系

以類似于跨越關(guān)系的查找的方式,在與您查詢的模型或模型相關(guān)的字段上的聚合和注釋可以包括遍歷反向關(guān)系。 此處也使用相關(guān)模型的小寫名稱和雙下劃線。

例如,我們可以查詢所有出版商,并用他們各自的總圖書庫存計數(shù)器進(jìn)行注釋(注意我們?nèi)绾问褂?nbsp;'book' 來指定 Publisher -> Book 反向外鍵跳轉(zhuǎn)):

>>> from django.db.models import Avg, Count, Min, Sum
>>> Publisher.objects.annotate(Count('book'))

(查詢結(jié)果里的每一個 Publisher 會有多余的屬性—— book__count 。)
我們也可以找出最古老的一本:

>>> Publisher.objects.aggregate(oldest_pubdate=Min('book__pubdate'))

(結(jié)果字典中會有一個叫 'oldest_pubdate' 的鍵。如果沒有指定這樣的別名,它將會是一個很長的名字 'book__pubdate__min' 。)
它不僅僅用于外鍵,它也適用于多對多關(guān)系。比如,我們能查詢每一個作者,作者(共同)創(chuàng)作的書籍總頁數(shù)(注意我們?nèi)绾问褂?'book' 來指定 Author -> Book 反向多對多跳轉(zhuǎn)):

>>> Author.objects.annotate(total_pages=Sum('book__pages'))

(結(jié)果集里的每一個 Author 會有一個額外的屬性——total_pages)如果沒有指定這樣的別名,它將會是一個很長的名字 book__pages__sum)
或查詢書籍的平均評分:

>>> Author.objects.aggregate(average_rating=Avg('book__rating'))

(結(jié)果字典里會有一個叫 'average_rating' 的鍵。如果沒有指定這樣的別名,它將會是一個很長的名字 'book__rating__avg'。)


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號