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

Python Django中如何按月份对DateField获取去重查询集?

针对Django模型按月份过滤及去重查询集的实现方案

嘿,作为Django新手能想到按月份过滤和去重的需求,已经很到位啦!Django ORM本身就提供了现成的方法来实现你的需求,不用自己写复杂的SQL,下面给你详细拆解:

一、按月份过滤查询集

要针对date字段按月份过滤,直接用Django ORM的**字段查找(Field Lookups)**功能里的__month即可:

# 过滤出所有10月份的记录
october_records = MyModel.objects.filter(date__month=10)

不过要注意,如果你的数据跨了多个年份,上面的写法会把所有年份的10月份记录都查出来。如果需要精确到「某年某月」,可以结合__year一起过滤:

# 过滤出2024年10月份的记录
october_2024_records = MyModel.objects.filter(date__year=2024, date__month=10)

二、获取按月份去重的查询集

如果要获取所有唯一的月份(准确说是唯一的「年月」组合,避免不同年份的同月份重复),可以用Django的数据库函数来截断日期或提取年月,再结合values()和distinct()实现:

方法1:用TruncMonth截断日期到月份(推荐)

TruncMonth是Django 1.10+引入的函数,它会把日期截断到当月的第一天(比如2024-10-15会变成2024-10-01),之后我们基于这个截断后的日期去重:

from django.db.models.functions import TruncMonth

# 获取所有唯一的年月,返回字典列表,每个字典包含'truncated_date'键(值为当月第一天)
unique_months = MyModel.objects.annotate(
    truncated_date=TruncMonth('date')
).values('truncated_date').distinct().order_by('truncated_date')

order_by('truncated_date')是为了让结果按时间顺序排列,方便查看。

方法2:提取年份和月份字段

如果你的Django版本较低(低于1.10),可以用ExtractYear和ExtractMonth分别提取年份和月份,再基于这两个字段去重:

from django.db.models.functions import ExtractYear, ExtractMonth

# 获取所有唯一的年月组合,返回字典列表,包含'year'和'month'键
unique_month_years = MyModel.objects.annotate(
    year=ExtractYear('date'),
    month=ExtractMonth('date')
).values('year', 'month').distinct().order_by('year', 'month')

进阶:同时获取月份的统计数据

如果除了去重的月份,你还想得到每个月的汇总数据(比如总金额、记录数),可以在annotate之后再添加聚合函数:

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

monthly_summary = MyModel.objects.annotate(
    month=TruncMonth('date')
).values('month').annotate(
    total_amount=Sum('amount'),  # 当月总金额
    record_count=Count('id')     # 当月记录条数
).order_by('month')

这样返回的结果里,每个条目都会包含对应的月份、总金额和记录数,非常实用~


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:52:19