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

Django中使用values()按月份分组统计分类金额总和的问题

按分类+月份统计金额总和的Django实现方法

1. 数据库层面分组统计

首先用Django的TruncMonth函数提取日期的年月信息(避免跨年度同月份混淆),结合Sum函数按分类和月份分组统计。

先导入必要模块:

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

执行查询语句:

query_result = model.objects.values(
    'category',
    month=TruncMonth('date')  # 提取当月第一天的datetime对象,包含完整年月
).annotate(
    total_amount=Sum('amount')
).order_by('category', 'month')

查询结果为字典列表,每条数据对应一个分类某一月的总金额:

[
    {'category': 'A', 'month': datetime.date(2024, 1, 1), 'total_amount': 100},
    {'category': 'A', 'month': datetime.date(2024, 2, 1), 'total_amount': 180},
    {'category': 'B', 'month': datetime.date(2024, 1, 1), 'total_amount': 150},
    {'category': 'B', 'month': datetime.date(2024, 2, 1), 'total_amount': 200},
]

2. 转换为嵌套字典格式

在视图中将查询结果整理成你需要的嵌套结构,同时收集所有月份用于表头展示:

from collections import defaultdict

category_month_totals = defaultdict(dict)
all_months = set()

for item in query_result:
    category = item['category']
    # 将月份格式化为易读的字符串,比如"2024-01"
    month_str = item['month'].strftime('%Y-%m')
    category_month_totals[category][month_str] = item['total_amount']
    all_months.add(month_str)

# 对月份排序,保证展示顺序正确
sorted_months = sorted(all_months)

处理后得到的category_month_totals即为目标格式:

{
    'A': {'2024-01': 100, '2024-02': 180},
    'B': {'2024-01': 150, '2024-02': 200}
}

3. 模板渲染表格

将category_month_totals和sorted_months传入模板后,按以下步骤渲染表格:

自定义模板过滤器

在app的templatetags目录下创建custom_filters.py,用于从字典中取值:

from django import template

register = template.Library()

@register.filter
def get(dictionary, key):
    return dictionary.get(key)

模板代码

加载过滤器并渲染表格:

{% load custom_filters %}

<table border="1">
    <thead>
        <tr>
            <th>Category</th>
            {% for month in sorted_months %}
                <th>{{ month }}</th>
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for category, month_totals in category_month_totals.items %}
            <tr>
                <td>{{ category }}</td>
                {% for month in sorted_months %}
                    <!-- 无数据的月份显示0 -->
                    <td>{{ month_totals|get:month|default:0 }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </tbody>
</table>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:27:15