本文為 留言評分功能 系列教學,第 11 篇:
- 使用 Django + Tailwind + Alpine.js 實作「五顆星評分」功能教學
- Django validators 驗證器完整教學
- Django PositiveSmallIntegerField 新手指南
- 在 esbuild 專案中整合 Alpine.js 的完整指南
- 使用 Alpine.js 建立星星評分表單 — 新手指南
- 深入理解 Alpine.js 中的 template 標籤使用指南
- Django 網站如何新增「星星評分」功能 — 後端接收邏輯
- Django 表單:如何讓使用者選擇性提交星星評分與留言
- Django 如何限制同一使用者只能對同一服務留言一次?
- Django 留言軟刪除邏輯|程式碼解析
- Django 計算評分摘要教學 — 使用 ORM 進行星等統計 👈 所在位置
- Python Django 使用 annotate、aggregate 統計教學
- 使用 Alpine.js 實作星級評分分佈 – 詳細教學
- Alpine.js 與 Tailwind CSS 動態樣式解析:為什麼有些樣式無法生效?
- Django 中使用 annotate() 與 Avg() 進行平均評分計算
在 Django 開發中,我們經常需要計算用戶對某項服務的評分統計,例如總評論數、平均分數以及各星等的分佈情況。
這篇文章將透過一段完整的 Django ORM 程式碼,帶你逐步理解如何使用 annotate()、aggregate() 等方法來計算這些數據,並附上詳細解釋與範例輸出。
範例程式碼
from django.db.models import Count, Avg
# ✅ 計算評分摘要
total_reviews = comments.count()
average_rating = comments.aggregate(Avg('rating'))['rating__avg']
# ✅ 建立 1~5 星的分佈 (確保所有星等都存在)
rating_summary = comments.values('rating').annotate(count=Count('rating'))
rating_distribution = {i: 0 for i in range(1, 6)}
for entry in rating_summary:
rating_distribution[entry['rating']] = entry['count']
程式碼目標
這段程式碼的主要目標是計算出:
- 每個星等的評論數量 (
rating_summary) - 總評論數 (
total_reviews) - 平均分數 (
average_rating) - 各星等的完整分佈 (
rating_distribution)
total_reviews — 計算總評論數
total_reviews = comments.count()解釋
.count()是 Django ORM 提供的內建方法,直接計算目前QuerySet中的總筆數。
範例輸出
15average_rating — 計算平均分數
average_rating = comments.aggregate(Avg('rating'))['rating__avg']解釋
.aggregate(Avg('rating'))- 使用
Avg()計算整個QuerySet中rating欄位的平均分數。
- 使用
.aggregate()會回傳一個字典,因此需要使用['rating__avg']來存取結果。
範例輸出
4.6建立 1~5 星的分佈
rating_summary — 計算每個評分的數量
rating_summary = comments.values('rating').annotate(count=Count('rating'))解釋
comments.values('rating')- 將
rating欄位的數據進行分組 (每個星等作為一組)。
- 將
.annotate(count=Count('rating'))- 使用
Count函數計算每個分組中rating的數量,並將結果儲存在count鍵中。
- 使用
範例輸出
[
{'rating': 5, 'count': 12},
{'rating': 4, 'count': 3}
]rating_distribution — 建立 1 到 5 星的分佈
rating_distribution = {i: 0 for i in range(1, 6)}解釋
- 建立一個 Python 字典,預設將 1 到 5 星的數量都設為
0。 - 即使某個星等沒有評論,也能正確顯示為
0。
範例輸出
{1: 0, 2: 0, 3: 0, 4: 0, 5: 0}延伸閱讀:Python 字典推導式詳解:新手指南
將 rating_summary 更新到分佈字典
for entry in rating_summary:
rating_distribution[entry['rating']] = entry['count']
解釋
- 這段程式碼會迭代
rating_summary(已計算的星等數量清單)。 - 將每個星等的數量更新到
rating_distribution字典中。
範例輸出
rating_summary = [{'rating': 5, 'count': 12}, {'rating': 4, 'count': 3}]
rating_distribution = {1: 0, 2: 0, 3: 0, 4: 3, 5: 12}
完整範例結果
評論數12
評論數3
評論數0
評論數0
評論數0
- 總評論數:
15 - 平均分數:
4.6 - 星等分佈:
{1: 0, 2: 0, 3: 0, 4: 3, 5: 12}
總結
這段 Django 程式碼透過 ORM 操作完成了以下幾個重要步驟:
- 計算每個評分的數量 (
annotate()與Count) - 計算總評論數 (
count()) - 計算平均分數 (
aggregate()與Avg) - 建立星等分佈 (
for迴圈 +dict)
希望這篇文章幫助你更清楚了解如何使用 Django ORM 進行資料統計。