Django DateTimeRangeField日期过滤问题:查询90天后数据返回空集
解决Django DateTimeRangeField筛选日期范围的问题
问题原因
你当前的查询返回空集,是因为timezone.now() + timezone.timedelta(days=90)生成的是带具体时分秒的时间(比如2022-11-29 22:52:07),而模型中存储的start_end_date是当天早间的时间段(9:15-10:00),这个具体时间点不在该范围内,所以__contains条件无法匹配到记录。
正确筛选方案
你的需求是筛选出日期范围覆盖90天后当天的记录,由于页面逻辑保证start_end_date的开始和结束日期为同一天,可通过以下两种方式实现:
方法1:使用范围重叠查询(推荐)
计算90天后当天的完整时间范围(从00:00到次日00:00),然后用__overlap筛选与该范围有重叠的记录:
from django.utils import timezone from psycopg2.extras import DateTimeTZRange # 计算90天后的日期 target_date = timezone.now() + timezone.timedelta(days=90) # 生成当天00:00到次日00:00的时间范围 target_date_range = DateTimeTZRange( target_date.replace(hour=0, minute=0, second=0, microsecond=0), target_date.replace(hour=0, minute=0, second=0, microsecond=0) + timezone.timedelta(days=1) ) # 执行筛选 results = MyModel.objects.filter(start_end_date__overlap=target_date_range)
方法2:匹配日期部分
直接筛选start_end_date的开始时间的日期等于90天后的日期:
from django.utils import timezone target_date = timezone.now() + timezone.timedelta(days=90) results = MyModel.objects.filter(start_end_date__start__date=target_date.date())
补充说明
__contains用于判断单个时间点是否在范围内部,适合精确时间点匹配;__overlap用于判断两个时间范围是否存在重叠,更适合日期级别的范围筛选;- 由于你的
start_end_date都是同一天的时间段,两种方法都能得到正确结果,方法1更通用(即使后续允许跨天范围也能生效)。
内容的提问来源于stack exchange,提问作者jimmy
相关产品推荐
相关产品推荐

