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

如何在Django ListView中获取关联模型字段的聚合总和?

解决Django中按Item统计item_sold总值并在ListView展示的问题

先帮你捋捋当前代码里的问题,再一步步给出解决方案~

首先你用When的方式不对哦,When是用来做条件筛选求和的,而你现在只是要统计每个Model_Item关联的所有Model_ItemTransaction里item_sold的总和,完全不需要用到它,直接用Sum关联反向字段就可以搞定。

1. 修正ListView的查询逻辑

先把views.py里的get_queryset改成下面这样:

from django.db.models import Sum
from django.db.models.functions import Coalesce

class View_Item(ListView):
    model = Model_Item
    # 记得替换成你实际的模板路径
    template_name = "items/item_list.html"

    def get_queryset(self):
        # 先调用父类的get_queryset获取基础查询集
        queryset = super().get_queryset()
        # 关联反向交易记录,统计item_sold的总和
        # 用Coalesce处理空值:如果没有交易记录,总和显示0而不是None
        queryset = queryset.annotate(
            total_sold=Coalesce(Sum('model_itemtransaction__item_sold'), 0.0)
        )
        return queryset

2. 优化模型的可读性(可选但推荐)

你的外键反向关系默认是model_itemtransaction_set,名字有点长,建议给Model_ItemTransaction的外键加个related_name,让代码更清晰:

class Model_ItemTransaction(models.Model):
    # 添加related_name="transactions",方便后续调用
    item = models.ForeignKey(Model_Item, to_field="item_name", related_name="transactions")
    item_sold = models.FloatField(null=True, blank=True)
    
    def __unicode__(self):
        # 原代码返回self.item会输出对象,改成转成字符串显示商品名更友好
        return str(self.item)

改完后,annotate里的求和代码就可以写成更直观的:

total_sold=Coalesce(Sum('transactions__item_sold'), 0.0)

3. 在模板中展示统计值

最后在你的ListView模板里,直接循环object_list,调用每个item的total_sold字段就行:

{% for item in object_list %}
    <div class="item-card">
        <h3>{{ item.item_name }}</h3>
        <p>累计销售总量:{{ item.total_sold }}</p>
    </div>
{% endfor %}

为什么原代码不行?

你之前写的Sum(When(model_itemtransaction__item_sold))是错误用法:When必须配合condition和then参数使用,比如用来统计“某个时间段内的销量”这种有条件的场景,而你现在是要所有关联交易的总和,直接用Sum关联反向字段就足够啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:39:29