
对于不超过 2000 行的 django queryset,无需引入 pandas 或 numpy,仅用内置 `aggregate()` 即可高效完成均值、求和、计数等常见统计操作,且全部在数据库层执行,性能更优、内存更省。
在 Django 开发中,当需要对查询结果进行简单统计(如均值、求和、行数统计)时,很多开发者习惯先将 QuerySet 转为 Python 列表或借助 Pandas 处理。但这种做法不仅增加依赖、占用额外内存,还会将全部数据从数据库拉取到应用层——对千行级数据虽可接受,却完全忽略了 Django 和底层数据库原生聚合能力的强大优势。
实际上,Django 提供了高度优化的 .aggregate() 方法,它将计算逻辑下推至数据库执行(如 PostgreSQL 的 AVG()、SUM()、COUNT()),仅返回最终标量结果,避免数据搬运开销。以问题中的需求为例:
from django.db.models import Avg, Sum, Count
# 假设模型名为 MyModel,字段为 T1_id、T2_id、T1_value、T2_value
result = MyModel.objects.filter(T1_id=1).aggregate(
x1=Avg('T1_value'), # T1_id == 1 的 T1_value 均值
x2=Sum('T2_value'), # T1_id == 1 的 T2_value 总和
x3=Count('*') # T1_id == 1 的记录总数
)
# 输出示例:{'x1': 2.0, 'x2': 0, 'x3': 1}
print(result)✅ 优势显著:
- 零额外依赖:纯 Django ORM,无需安装 pandas、numpy 等重型库;
- 极致高效:数据库直接计算,网络传输量趋近于零(仅返回几个数字);
- 原子安全:单次查询完成所有指标,避免多次 filter() 导致的 N+1 查询风险;
- 可组合性强:支持链式过滤(如 .filter(status='active', created__year=2024))、多条件聚合,也兼容 F() 表达式与条件聚合(Case/When)。
⚠️ 注意事项:
- 若需对同一 QuerySet 执行多种分组逻辑(如按 T1_id 分组后分别计算各组的均值与总和),应改用 .values('T1_id').annotate(...);
- Count('*') 等价于 Count(1),比 Count('id') 更稳妥(避免因字段为空导致计数偏差);
- 聚合字段若存在 NULL,Avg 和 Sum 默认自动忽略(符合 SQL 标准),如需包含 NULL 作为 0 处理,需结合 Coalesce:
from django.db.models import Coalesce, Value Avg(Coalesce('T1_value', Value(0)))
综上,面对中小规模数据的常规统计需求,优先使用 Django 原生聚合不仅是“够用”的选择,更是更专业、更健壮、更符合 Web 应用数据流设计原则的实践方式。










