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

如何在Django中通过for循环按双条件计算列总和

解决Django中按用户+场地分组统计积分总和的问题

需求说明

需要统计指定用户在每个场地的积分总和,示例数据及预期结果如下:

原始数据

用户场地积分
User_1Venue_A50
User_1Venue_B25
User_2Venue_A1
User_1Venue_A50
User_2Venue_A1
User_1Venue_C25

预期结果

用户场地总积分
User_1Venue_A100
User_1Venue_B25
User_1Venue_C25

当前代码问题

  1. 仅计算了用户所有场地的积分总和,未按场地分组统计
  2. 求和逻辑与循环查询集分离,无法在模板中对应到单个场地的积分总和

修改方案

1. 更新views.py

使用Django ORM的values+annotate实现按场地分组求和,替代原来的aggregate:

from django.db.models import Sum

def user_loyalty_card(request):
    # 过滤当前用户,按场地分组并统计积分总和
    venue_points = Itemised_Loyatly_Card.objects.filter(user=request.user.id)\
        .values('user', 'venue__id', 'venue__name')  # 根据Venue模型实际字段调整,比如name是场地名称
        .annotate(total_points=Sum('add_points'))\
        .order_by('venue__name')  # 可选:按场地名称排序

    return render(request, "main/account/user_loyalty_card.html", {'venue_points': venue_points})

2. 更新模板

循环分组后的查询集,直接展示每个场地的总积分:

<table class="s-table">
    <thead>
        <tr>
            <th style="text-align: left;">用户</th>
            <th style="text-align: center;">场地</th>
            <th style="text-align: right;">总积分</th>
        </tr>
    </thead>
    <tbody>
        {% for item in venue_points %}
        <tr>
            <td style="text-align: left;">{{ item.user.username }}</td>  <!-- 根据UserProfile实际字段调整 -->
            <td style="text-align: center;">{{ item.venue__name }}</td>
            <td style="text-align: right;">{{ item.total_points }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

关键说明

  • values('user', 'venue__id', 'venue__name')指定分组依据,确保每个场地作为独立分组
  • annotate(total_points=Sum('add_points'))为每个分组计算积分总和,生成total_points字段供模板调用
  • 该方案仅需一次数据库查询,性能优于在模板中循环求和

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:25:44