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

Django实现忽略年份的日期范围过滤方法

Django 忽略年份按日月维度过滤日期数据实现方案

你需要提取日期字段的月份、日两个维度单独做匹配,不需要用到年份信息,下面是两种常用实现方式:


方案1:Django 3.2+ 官方推荐实现(适配所有数据库后端)

使用Django内置的Extract函数提取月、日字段后做过滤:

  1. 先导入依赖模块:
from django.db.models import Q
from django.db.models.functions import Extract
  1. 普通不跨年末的范围查询示例(比如查询3月15日到9月10日之间的所有生日记录):
start_month = 3
start_day = 15
end_month = 9
end_day = 10

Sample.objects.annotate(
    # 单独提取生日的月份和日
    birth_month=Extract('birthday', 'month'),
    birth_day=Extract('birthday', 'day')
).filter(
    # 匹配大于等于起始日月
    Q(birth_month__gt=start_month) | Q(birth_month=start_month, birth_day__gte=start_day)
).filter(
    # 匹配小于等于结束日月
    Q(birth_month__lt=end_month) | Q(birth_month=end_month, birth_day__lte=end_day)
)
  1. 跨年末的范围查询示例(比如查询12月20日到次年1月10日之间的所有生日记录):
Sample.objects.annotate(
    birth_month=Extract('birthday', 'month'),
    birth_day=Extract('birthday', 'day')
).filter(
    Q(birth_month=12, birth_day__gte=20) | Q(birth_month=1, birth_day__lte=10)
)

方案2:旧版本Django兼容实现

如果你使用的Django版本低于3.2,可以调用对应数据库的原生日期函数实现,以MySQL为例:

from django.db.models import Q

Sample.objects.extra(
    where=[
        'MONTH(birthday) > %s OR (MONTH(birthday) = %s AND DAYOFMONTH(birthday) >= %s)',
        'MONTH(birthday) < %s OR (MONTH(birthday) = %s AND DAYOFMONTH(birthday) <= %s)'
    ],
    params=[start_month, start_month, start_day, end_month, end_month, end_day]
)

注意:extra方法已被Django官方标记为废弃,仅在无法升级Django版本时临时使用,优先选择方案1。


闰年特殊处理

如果业务场景涉及2月29日的生日记录,可以根据需求额外补充判断逻辑:

  • 非闰年时可将2月29日的匹配规则对齐到2月28日
  • 仅当查询范围包含2月29日时才返回对应生日的记录

内容的提问来源于stack exchange,提问作者John R Perry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:18:03