You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django最佳实践:按模型ID汇总总金额的实现方案

最佳实现方案

针对你的需求,有两种主流实现方式,分别适用于不同场景:

1. 数据库层面聚合(推荐,效率优先)

如果你的reports是Django ORM的QuerySet,直接在数据库层面做分组求和是最优解——避免把大量数据加载到内存,减少计算开销。

示例代码:

from django.db.models import Sum

# 按num分组,聚合total_amount的总和,同时保留title(若同一num对应多个title,需根据业务确定取法,这里默认取分组内第一个)
aggregated_data = reports.values('num', 'title').annotate(total_sum=Sum('total_amount'))

data = []
for item in aggregated_data:
    data.append(DataModel(
        model_id=item['num'],
        title=item['title'],
        total_price=item['total_sum']
    ))

注意:如果同一num对应不同title,需要调整聚合逻辑,比如使用First('title')确保取到固定值,或者业务上保证num与title一一对应。

2. Python内存中处理(适合无法数据库聚合的场景)

如果reports已经是内存中的对象列表,或无法通过数据库聚合处理,可以用字典分组或itertools.groupby实现:

方式一:用defaultdict分组(简单直观)

from collections import defaultdict

sum_map = defaultdict(lambda: {'total': 0, 'title': ''})

for report in reports:
    key = report.num
    sum_map[key]['total'] += report.total_amount
    # 仅在首次遇到该key时设置title,避免被后续不同title覆盖
    if not sum_map[key]['title']:
        sum_map[key]['title'] = report.title

# 转换为DataModel列表
data = [
    DataModel(
        model_id=model_id,
        title=info['title'],
        total_price=info['total']
    ) for model_id, info in sum_map.items()
]

方式二:用itertools.groupby(需先排序)

from itertools import groupby

# 先按num排序,确保同组元素连续(groupby要求同组元素相邻)
sorted_reports = sorted(reports, key=lambda x: x.num)

data = []
for num, report_group in groupby(sorted_reports, key=lambda x: x.num):
    total_price = 0
    title = ''
    for report in report_group:
        total_price += report.total_amount
        if not title:
            title = report.title
    data.append(DataModel(
        model_id=num,
        title=title,
        total_price=total_price
    ))

内容的提问来源于stack exchange,提问作者Mehdi Aria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 12:20:39