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

如何在Django中按出生日期剩余天数过滤列表,展示30天内即将过生日的用户

报错根因

该报错是因为两类datetime对象类型不匹配:

  • ORM查询返回的dateOfBirth是带时区信息的offset-aware类型
  • datetime.today()生成的是不带时区信息的offset-naive类型
    两类对象不支持直接做算术运算。
报错修复代码

如果是Django环境,直接使用框架内置的时区工具统一时间类型即可,同时补充生日年份适配逻辑(避免出现当年生日已过,剩余天数为负的情况):

from django.utils import timezone

# 获取当前带时区的日期,和数据库字段时区保持一致
today = timezone.localdate()
customers = Customer.objects.all()[:10]
for i in customers:
    # 取出生日的月日,适配为当年的生日日期
    try:
        current_year_birthday = i.dateOfBirth.replace(year=today.year).date()
    except ValueError:
        # 兼容2月29日生日的平年场景,调整为2月28日
        current_year_birthday = i.dateOfBirth.replace(year=today.year, month=2, day=28).date()
    # 当年生日已过的话,用明年生日计算剩余天数
    if current_year_birthday < today:
        current_year_birthday = current_year_birthday.replace(year=today.year + 1)
    remaining_days = (current_year_birthday - today).days
    print(f"用户{i.name}剩余生日天数:{remaining_days}")
完整实现30天内生日用户查询

可以直接在ORM层完成计算和过滤,性能更高,直接返回你需要的字段:

from django.utils import timezone
from django.db.models import F, ExpressionWrapper, IntegerField, Case, When, DateTimeField

today = timezone.localdate()
current_year = today.year

upcoming_birthday_users = Customer.objects.annotate(
    # 计算当年生日日期
    current_year_birth = ExpressionWrapper(
        F('dateOfBirth') + (current_year - F('dateOfBirth__year')) * timezone.timedelta(days=365),
        output_field=DateTimeField()
    ),
    # 当年生日已过的话,顺延到下一年
    final_calc_birth = Case(
        When(current_year_birth__date__lt=today, then=F('current_year_birth') + timezone.timedelta(days=365)),
        default=F('current_year_birth'),
        output_field=DateTimeField()
    ),
    # 计算剩余天数
    remaining_days = ExpressionWrapper(
        (F('final_calc_birth') - timezone.now()).days,
        output_field=IntegerField()
    )
# 过滤30天内生日的用户,按剩余天数升序排列
).filter(remaining_days__lte=30, remaining_days__gte=0).order_by('remaining_days').values('name', 'dateOfBirth', 'remaining_days')

遍历upcoming_birthday_users即可获取所有符合要求的用户数据,将remaining_days字段格式化为还有X天即可匹配你要的列表展示效果。

如需调整2月29日生日的平年适配规则,修改对应的异常捕获分支即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:27:03