如何在Django中统计月度收入、支出、净收入并在模板循环展示
实现方案
原有代码的核心问题是两个独立的Django QuerySet无法直接做数值运算,也没有自动按月份关联匹配的逻辑,同时还存在语法错误(context中net_monthly_income末尾多了多余引号,视图函数缺少render返回)。
1. 视图层修改
首先导入需要的依赖,再通过字典映射将收入、支出按月份关联,兼容单月只有收入/只有支出的场景:
from django.db.models import Sum from django.db.models.functions import TruncMonth from django.shortcuts import render def monthly_Income(request): # 统计月度收入,转为 月份:收入额 字典 income_qs = Income.objects.annotate(month=TruncMonth('date'))\ .values('month')\ .annotate(total_income=Sum('amount')) income_map = {item['month']: item['total_income'] for item in income_qs} # 统计月度支出,转为 月份:支出额 字典 expend_qs = Expenditure.objects.annotate(month=TruncMonth('date'))\ .values('month')\ .annotate(total_expend=Sum('amount')) expend_map = {item['month']: item['total_expend'] for item in expend_qs} # 合并所有出现过的月份,按时间倒序排序 all_months = set(income_map.keys()).union(set(expend_map.keys())) sorted_months = sorted(all_months, reverse=True) # 组装最终统计数据 monthly_stats = [] for month in sorted_months: income = income_map.get(month, 0) expend = expend_map.get(month, 0) monthly_stats.append({ 'month': month, 'total_income': income, 'total_expend': expend, 'net_income': income - expend }) context = { 'monthly_stats': monthly_stats } return render(request, '你的模板文件路径.html', context)
2. 模板层渲染
直接遍历组装好的统计列表即可,以下是表格形式的渲染代码:
注意:如果要使用
intcomma格式化数字,需要先在settings.py的INSTALLED_APPS中添加django.contrib.humanize,并在模板开头加载{% load humanize %}。
{% load humanize %} <table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse;"> <thead> <tr> <th>统计月份</th> <th>总收入</th> <th>总支出</th> <th>净收入</th> </tr> </thead> <tbody> {% for item in monthly_stats %} <tr> <td>{{ item.month|date:"Y年m月" }}</td> <td>{{ item.total_income|intcomma }}</td> <td>{{ item.total_expend|intcomma }}</td> <td>{{ item.net_income|intcomma }}</td> </tr> {% empty %} <tr> <td colspan="4" align="center">暂无收支数据</td> </tr> {% endfor %} </tbody> </table>
内容的提问来源于stack exchange,提问作者apollos
相关产品推荐
相关产品推荐

