如何对Django中存储对象数组的JSONField字段执行sum注解求和?
Django ORM注解实现JSON数组内字段求和方案
前置条件
确保使用Django 3.1及以上版本,数据库支持JSON操作(PostgreSQL 12+、MySQL 8.0+、SQLite 3.31.0+均可支持)
实现代码
PostgreSQL 场景(官方推荐首选)
PostgreSQL对JSON操作支持最完善,可直接通过jsonb_path_query_sum函数一步完成求和:
from django.db.models import FloatField, Func, QuerySet from .models import MyModel # 注解查询集,为每个实例新增order_total字段存储price总和 queryset = MyModel.objects.annotate( order_total=Func( "orders", function="jsonb_path_query_sum", template="%(function)s(%(expressions)s, '$.**.price')", output_field=FloatField(), ) ) # 访问示例 for instance in queryset: # 你的示例数据对应输出1100 print(instance.order_total)
MySQL 场景
MySQL 8.0+可使用JSON路径求和函数实现:
from django.db.models import FloatField, Func, QuerySet from .models import MyModel queryset = MyModel.objects.annotate( order_total=Func( "orders", function="JSON_VALUE", template="%(function)s(%(expressions)s, '$.sum($[*].price)')", output_field=FloatField(), ) )
扩展用法:按分类分组求和所有订单总金额
如果需要统计每个分类下所有关联订单的总金额,可在注解后配合聚合实现:
from django.db.models import Sum category_total = queryset.values("category_id").annotate( total_amount=Sum("order_total") )
注意事项
- 若PostgreSQL中你的
orders字段使用的是json类型而非默认的jsonb类型,将函数名修改为json_path_query_sum即可 - 空数组场景下返回的求和结果为
0,空值场景下可配合Coalesce处理默认值
内容的提问来源于stack exchange,提问作者Bimal Prasad Pandey
相关产品推荐
相关产品推荐

