Django ORM 聚合函数与复杂查询实战指南

蓝鲸
蓝鲸
发布时间:2026-10-11| 3人浏览过
原创

本文深入解析Django ORM中的聚合函数应用。通过具体代码示例,详细演示如何使用Aggregate进行全局统计(如Sum、Avg、Count、Max、Min),以及利用Annotate结合F表达式进行分组计算。同时,文章涵盖Q表达式在构建复杂逻辑查询(与、或、非)中的具体用法,帮助开发者高效处理数据库统计与过滤任务。

聚合函数的核心机制

Django ORM 提供了与 SQL 标准一致的聚合函数,主要位于 django.db.models 模块中。这些函数包括 Sum、Avg、Count、Max 和 Min。理解其工作机制的关键在于区分两种执行方式:aggregate() 与 annotate()。

  • aggregate():返回一个字典,执行的是全局聚合,不产生分组(相当于 SQL 中不带 GROUP BY 的查询)。
  • annotate():返回 QuerySet,为模型实例添加聚合字段,通常配合分组使用(相当于 SQL 中的 GROUP BY)。

模型定义与数据准备

为了演示聚合函数的具体用法,我们首先定义一组关联模型。这些模型涵盖了作者、出版社、图书以及图书订单,用于展示跨表聚合与字段计算。

class Author(models.Model):
     """作者模型"""
     name = models.CharField(max_length=100)
     age = models.IntegerField()
     email = models.EmailField()

     class Meta:
         db_table = 'author'


class Publisher(models.Model):
     """出版社模型"""
     name = models.CharField(max_length=300)

     class Meta:
         db_table = 'publisher'


class Book(models.Model):
     """图书模型"""
     name = models.CharField(max_length=300)
     pages = models.IntegerField()
     price = models.FloatField()
     rating = models.FloatField()
     author = models.ForeignKey(Author,on_delete=models.CASCADE)
     publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)

     class Meta:
         db_table = 'book'


class BookOrder(models.Model):
     """图书订单模型"""
     book = models.ForeignKey("Book",on_delete=models.CASCADE)
     price = models.FloatField()

     class Meta:
         db_table = 'book_order'

全局聚合:使用 Aggregate

aggregate() 方法用于对 QuerySet 进行整体统计。它返回一个字典,键名默认为 field__function 格式(例如 price__avg)。

1. 基础聚合:求平均值

默认情况下,返回的键名由字段名和函数名组成。通过关键字参数,可以自定义返回结果的键名,使结果更易读。

from django.db.models import Avg
# 默认返回 {'price__avg': 100.5}
result = Book.objects.aggregate(Avg('price'))
print(result)

# 自定义键名,返回 {'my_avg': 100.5}
result = Book.objects.aggregate(my_avg=Avg('price'))
print(result)

2. 计数与去重:Count

Count 用于统计对象数量。其 distinct 参数默认为 False。当设置为 True 时,聚合函数会先去除重复值再进行计数,这在处理外键关联时非常有用。

from django.db.models import Count
# 统计图书总数
result = Book.objects.aggregate(book_num=Count('id'))

# 统计作者邮箱去重后的数量
result = Author.objects.aggregate(count=Count('email', distinct=True))

3. 极值查询:Max 与 Min

获取指定字段的最大值和最小值,返回格式同样遵循 field__max 和 field__min 的规则。

from django.db.models import Max, Min
# 获取作者年龄的最大值和最小值
result = Author.objects.aggregate(Max('age'), Min('age'))

4. 跨表聚合:Sum

利用 Django 的双下划线语法,可以跨越外键进行聚合。例如,计算每本图书关联的所有订单价格总和。

from django.db.models import Sum
# 注意:这里使用 annotate 为 Book 添加 total 字段
result = Book.objects.annotate(total=Sum("bookorder__price"))

分组聚合:使用 Annotate

与 aggregate 不同,annotate() 用于为 QuerySet 中的每个对象添加聚合数据。这通常用于“分组”场景,例如计算每个作者名下图书的总价格。

from django.db.models import Sum
# 为每个 Book 对象添加其关联订单的总价格字段 'total'
books_with_total = Book.objects.annotate(total=Sum("bookorder__price"))
for book in books_with_total:
    print(book.name, book.total)

动态字段计算:F 表达式

F 表达式允许在数据库层面直接引用字段值进行更新或过滤,而无需先将数据加载到 Python 内存中。这提高了性能并避免了并发更新时的数据覆盖问题。

from django.db.models import F
# 将所有图书的价格增加 10
Book.objects.update(price=F("price") + 10)

复杂条件查询:Q 表达式

当过滤条件涉及“或”(OR)或复杂的逻辑组合时,Q 表达式是必要的工具。它支持与(&)、或(|)和非(~)操作。

1. 逻辑与(AND)

虽然多个 filter 参数默认是“与”关系,但使用 Q 表达式可以更清晰地表达复杂逻辑。

# 不使用 Q 表达式(隐式 AND)
books = Book.objects.filter(price__gte=100, rating__gte=4.85)

# 使用 Q 表达式(显式 AND)
books = Book.objects.filter(Q(price__gte=100) & Q(rating__gte=4.85))

2. 逻辑非(NOT)

使用波浪号 ~ 可以表示逻辑非,用于排除特定条件的数据。

# 价格大于100 且 书名不包含 '传' 字的图书
books = Book.objects.filter(Q(price__gte=100) & ~Q(name__icontains='传'))

总结

Django 的 ORM 聚合功能强大且灵活。掌握 aggregate 与 annotate 的区别,熟练运用 F 表达式进行高效更新,以及利用 Q 表达式处理复杂查询,是提升 Django 应用数据处理能力的关键。通过合理组合这些工具,可以编写出既高效又易读的数据库操作代码。

以上就是 Django 聚合函数与复杂查询实战的详细内容,更多关于 Django ORM 高级用法、数据库优化及模型设计的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。