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

如何用单条Django查询按月份汇总指定条件的valor_da_operacao?

Django查询实现按月份分组汇总股息数据

问题描述

我的Movimentacao模型定义如下:

class Movimentacao(models.Model):
    entrada_saida = models.CharField(max_length=100)
    date = models.DateField()
    movimentacao = models.CharField(max_length=200)
    produto = models.CharField(max_length=300)
    instituicao = models.CharField(max_length=200)
    quantidade = models.IntegerField()
    preco_unitario = models.DecimalField(max_digits=19, decimal_places=2)
    valor_da_operacao = models.DecimalField(max_digits=19, decimal_places=2)

我需要筛选出produto字段等于"dividendo"的数据,按date字段的月份分组,汇总每个月的valor_da_operacao字段值,最终要得到这样的格式:

{"dict": [["2022-Jan", 1.530], ["2022-Feb", 422], ["2022-Mar", 1.822]]}

请问怎么用单条Django查询实现这个需求?


解决方案

你可以通过Django ORM结合数据库函数来实现,以下是具体代码:

通用兼容版本(适配多数据库)

首先导入需要的模块:

from django.db.models import Sum
from django.db.models.functions import ExtractYear, ExtractMonth
from django.utils.dateformat import DateFormat

然后编写查询并转换格式:

# 执行分组汇总查询
query_results = Movimentacao.objects.filter(produto='dividendo') \
    .annotate(
        year=ExtractYear('date'),
        month=ExtractMonth('date')
    ) \
    .values('year', 'month') \
    .annotate(total_valor=Sum('valor_da_operacao')) \
    .order_by('year', 'month')

# 转换为目标格式
final_result = {
    "dict": [
        [f"{item['year']}-{DateFormat(item['month']).format('M')}", float(item['total_valor'])]
        for item in query_results
    ]
}

PostgreSQL专属优化版本

如果你的项目用的是PostgreSQL数据库,可以直接在查询中生成YYYY-Mon格式的日期字符串,减少后续格式转换步骤:

from django.db.models import Sum, Value
from django.db.models.functions import ExtractYear, Concat, ToChar

# 直接生成日期格式并分组汇总
query_results = Movimentacao.objects.filter(produto='dividendo') \
    .annotate(
        year_month=Concat(
            ExtractYear('date'),
            Value('-'),
            ToChar('date', 'Mon')
        )
    ) \
    .values('year_month') \
    .annotate(total_valor=Sum('valor_da_operacao')) \
    .order_by('year_month')

# 转换为目标格式
final_result = {
    "dict": [[item['year_month'], float(item['total_valor'])] for item in query_results]
}

代码说明

  • filter(produto='dividendo'):精准筛选出产品为股息的记录
  • annotate(year=ExtractYear('date'), month=ExtractMonth('date')):从date字段中提取年份和月份,用于后续分组
  • values('year', 'month'):指定按年份和月份进行分组
  • annotate(total_valor=Sum('valor_da_operacao')):对每个分组的valor_da_operacao字段求和
  • 最后通过列表推导式将查询结果转换为你需要的格式,同时把Decimal类型的求和结果转为float,年份和月份拼接成YYYY-Mon的形式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:15:31