电商项目中如何统计新订单内各产品的待打包总数量?
解决Django电商项目中统计新订单产品总数量的问题
嘿,我来帮你搞定这个统计需求!根据你给出的三个关联模型,我们可以通过Django的ORM查询API高效统计新订单(order_status=1)里各产品的总待打包数量。
核心思路
你的模型关联关系是:Orders ← 一对多 → OrderItems ← 多对一 → Products。我们需要筛选出所有状态为“新订单”的订单项,然后按产品分组,对数量求和。
重要提醒
首先要提一下:你的OrderItems里的quantity字段是CharField,如果存储的是数字,必须先转换成数值类型才能正确求和。建议你把这个字段改成IntegerField,这样更符合业务逻辑,也能避免类型转换的麻烦。如果暂时没法改字段类型,我们可以用Django的Cast函数来处理。
解决方案一:从Products模型出发查询
这种方式可以直接获取产品对象及其对应总数量:
from django.db.models import Sum, IntegerField from django.db.models.functions import Cast # 筛选出有新订单的产品,统计总数量 products_with_total = Products.objects.filter( # 通过反向关联(related_name='product_order')筛选属于新订单的订单项 product_order__order__order_status=1 ).annotate( # 把字符类型的quantity转成整数后求和 total_quantity=Sum(Cast('product_order__quantity', IntegerField())) ).values('product_name', 'total_quantity') # 输出你想要的格式 for item in products_with_total: print(f"{item['product_name']} - {item['total_quantity']}")
解决方案二:从OrderItems模型出发分组统计
这种方式更直接,先筛选新订单的订单项,再按产品分组求和:
from django.db.models import Sum, IntegerField from django.db.models.functions import Cast # 筛选新订单的订单项,按产品名称分组统计数量 order_items_summary = OrderItems.objects.filter( order__order_status=1 ).values( 'product__product_name' # 按产品名称分组 ).annotate( total_quantity=Sum(Cast('quantity', IntegerField())) ).order_by('product__product_name') # 可选:按产品名称排序 # 输出结果 for item in order_items_summary: print(f"{item['product__product_name']} - {item['total_quantity']}")
进阶:包含所有产品(包括数量为0的)
如果需要展示所有产品,哪怕该产品没有新订单(数量显示为0),可以用子查询实现:
from django.db.models import Sum, IntegerField, OuterRef, Subquery from django.db.models.functions import Cast # 子查询:统计单个产品的新订单总数量 subquery = OrderItems.objects.filter( product=OuterRef('pk'), order__order_status=1 ).annotate( total=Sum(Cast('quantity', IntegerField())) ).values('total')[:1] # 给所有产品添加总数量字段,无订单的显示0 all_products_with_total = Products.objects.annotate( total_quantity=Subquery(subquery, output_field=IntegerField()) ).values('product_name', 'total_quantity') for item in all_products_with_total: print(f"{item['product_name']} - {item['total_quantity'] or 0}")
内容的提问来源于stack exchange,提问作者Tech
相关产品推荐
相关产品推荐

