如何在Django中通过for循环按双条件计算列总和
解决Django中按用户+场地分组统计积分总和的问题
需求说明
需要统计指定用户在每个场地的积分总和,示例数据及预期结果如下:
原始数据
| 用户 | 场地 | 积分 |
|---|---|---|
| User_1 | Venue_A | 50 |
| User_1 | Venue_B | 25 |
| User_2 | Venue_A | 1 |
| User_1 | Venue_A | 50 |
| User_2 | Venue_A | 1 |
| User_1 | Venue_C | 25 |
预期结果
| 用户 | 场地 | 总积分 |
|---|---|---|
| User_1 | Venue_A | 100 |
| User_1 | Venue_B | 25 |
| User_1 | Venue_C | 25 |
当前代码问题
- 仅计算了用户所有场地的积分总和,未按场地分组统计
- 求和逻辑与循环查询集分离,无法在模板中对应到单个场地的积分总和
修改方案
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
相关产品推荐
相关产品推荐

