Django ORM - 聚合查询
封面图
•
2025-10-22
•
Django教程
0
0
0
0
在 Django ORM 中,**聚合查询**(Aggregation)用于对数据库中的数据进行统计计算,例如求和、平均值、最大值、最小值等。Django 提供了 `annotate()` 和 `aggregate()` 两个主要方法来执行聚合操作。 --- ## ✅ 常见的聚合函数 | 聚合函数 | 说明 | |----------|------| | `Sum()` | 求和 | | `Avg()` | 平均值 | | `Count()` | 计数 | | `Max()` | 最大值 | | `Min()` | 最小值 | | `StdDev()` | 标准差 | | `Variance()` | 方差 | 这些函数都位于 `django.db.models` 模块中。 --- ## 📌 示例模型 假设我们有一个 `Book` 模型: ```python from django.db import models class Book(models.Model): title = models.CharField(max_length=100) author = models.ForeignKey('Author', on_delete=models.CASCADE) price = models.DecimalField(max_digits=10, decimal_places=2) rating = models.IntegerField(default=0) class Author(models.Model): name = models.CharField(max_length=100) ``` --- ## 🔍 1. 使用 `aggregate()` `aggregate()` 返回一个字典,包含所有聚合的结果。 ### 示例:计算所有书的总价格 ```python from django.db.models import Sum total_price = Book.objects.aggregate(total_price=Sum('price')) print(total_price) # 输出: {'total_price': 1234.56} ``` ### 示例:计算所有书的平均价格 ```python from django.db.models import Avg avg_price = Book.objects.aggregate(avg_price=Avg('price')) print(avg_price) # 输出: {'avg_price': 24.69} ``` ### 示例:计算作者数量 ```python from django.db.models import Count author_count = Book.objects.aggregate(author_count=Count('author')) print(author_count) # 输出: {'author_count': 10} ``` --- ## 🧩 2. 使用 `annotate()` `annotate()` 是在每个对象上添加一个新的字段,通常是基于该对象的某些属性进行计算。 ### 示例:为每本书添加评分总和(假设每本书有多个评分) ```python from django.db.models import Sum books = Book.objects.annotate(total_rating=Sum('rating')) for book in books: print(book.title, book.total_rating) ``` > 注意:如果 `rating` 是一个字段,上面的写法可能不适用,应使用关联模型。 ### 更准确的例子(假设有 `Review` 模型): ```python class Review(models.Model): book = models.ForeignKey(Book, on_delete=models.CASCADE) rating = models.IntegerField() ``` #### 为每本书计算总评分: ```python from django.db.models import Sum books = Book.objects.annotate(total_rating=Sum('review__rating')) for book in books: print(f"{book.title}: {book.total_rating}") ``` --- ## 🧠 3. 组合聚合(Group By) 如果你需要按某个字段分组并聚合,可以使用 `values()` 或 `values_list()` 结合 `annotate()`。 ### 示例:按作者统计书籍数量 ```python from django.db.models import Count author_books = Book.objects.values('author__name').annotate(count=Count('id')) for item in author_books: print(f"Author: {item['author__name']}, Books: {item['count']}") ``` ### 示例:按作者统计平均评分 ```python from django.db.models import Avg author_avg_rating = Book.objects.values('author__name').annotate(avg_rating=Avg('rating')) for item in author_avg_rating: print(f"Author: {item['author__name']}, Average Rating: {item['avg_rating']}") ``` --- ## 🛠️ 小贴士 - `aggregate()` 返回的是整个查询集的汇总结果。 - `annotate()` 是针对每一个对象的附加字段。 - 使用 `values()` 可以实现类似 SQL 的 `GROUP BY` 功能。 - 如果你需要更复杂的聚合逻辑(如自定义聚合),可以使用 `Func` 类或编写原始 SQL 查询。 --- ## ✅ 总结 | 方法 | 用途 | 返回类型 | |------|------|----------| | `aggregate()` | 整体统计 | 字典 | | `annotate()` | 为每个对象添加字段 | QuerySet | | `values()` + `annotate()` | 分组统计 | QuerySet | --- 如果你有具体的模型结构或需求,我可以帮你写出对应的聚合查询代码 😊
上一篇:
Django ORM - 多表实例
下一篇:
Django Auth介绍
标题录入,一次不能超过6条
返回顶部
留言
留言
评论