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

Django QuerySet注解分组:合并同一账单多笔交易数据的技术问询

解决同一账单多笔交易合并为单条记录的问题

你遇到的核心问题是Invoice和TransactionInvoice是一对多关联,直接引用invoice__transaction_invoice__transaction_amount会让Django QuerySet生成笛卡尔积,导致同一账单对应多条交易记录。要实现合并展示,我们只需要用聚合函数对交易金额求和,就能让每条账单只返回一条汇总数据。

步骤1:修改QuerySet,用Sum聚合交易金额

首先要导入Sum聚合函数,然后把直接引用交易金额的逻辑替换为求和操作:

from django.db.models import Sum, F, Count

# 基础查询条件保持不变
order_list = Order.objects.filter(is_deleted=0, order_status__in=[4], order_type=0)

# 关键修改:用Sum聚合同一账单下的所有交易金额
order_list_data = order_list.annotate(
    customer_gross_sum=F('invoice__original_amount') - F('invoice__discount_amount') + F('invoice__tax_amount'),
    dcount=Count('user_id'),
    # 对当前账单关联的所有交易金额求和
    customer_transactions=Sum('invoice__transaction_invoice__transaction_amount')
)

为什么这样能解决问题?

  • 之前直接访问invoice__transaction_invoice__transaction_amount时,Django会为每个关联的交易生成一条Order记录(相当于做了表的笛卡尔积关联);
  • 使用Sum函数后,Django会自动对同一Order(对应同一账单)下的所有交易金额求和,并且每条Order只返回一条汇总记录,完美合并多笔交易数据。

步骤2:模板适配(可选优化)

你的表格模板可以直接沿用,不过可以加个小优化处理无交易的情况:

<table id="table">
 <thead>
 <td class="no-sort">Sl No</td>
 <td class="no-sort">BILL DATE</td>
 <td class="no-sort">BILL NO</td>
 <td>BILL VALUE (Rs)</td>
 <td>PAYMENT (Rs)</td>
 <td>BALANCE (Rs)</td>
 </thead>
 {% for data in order_list_data %}
 <tr>
 <td>{{forloop.counter}}</td>
 <td>{{data.invoice.bill_date}}</td>
 <td>{{data.invoice.bill_no}}</td>
 <td>{{data.customer_gross_sum}}</td>
 <td>{{data.customer_transactions|default:0}}</td> <!-- 无交易时显示0 -->
 <td>{{data.customer_gross_sum|sub:data.customer_transactions|default:0}}</td> <!-- 自动计算余额,可选 -->
 </tr>
 {% endfor %}
</table>

如果要使用上面的余额计算逻辑,需要先在项目中注册一个减法模板过滤器,或者也可以直接在QuerySet里提前计算余额字段:

# 在annotate里新增余额字段
order_list_data = order_list.annotate(
    # ... 其他字段保持不变
    balance=F('customer_gross_sum') - Sum('invoice__transaction_invoice__transaction_amount')
)

内容的提问来源于stack exchange,提问作者surya raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 16:19:07