Django过滤时如何包含起止日期?解决range不包含结束日期问题
问题
在views.py中执行这段代码时:
if request.method == "POST": from_date = request.POST.get("from_date") f_date = datetime.datetime.strptime(from_date,'%Y-%m-%d') print(f_date) to_date = request.POST.get("to_date") t_date = datetime.datetime.strptime(to_date, '%Y-%m-%d') print(t_date) check_box_status = request.POST.get("new_records", None) print(check_box_status) drop_down_status = request.POST.get("field") print(drop_down_status) if check_box_status is None: get_records_by_date = Scrapper.objects.filter(start_time__range=(f_date, t_date))
Scrapper.objects.filter(start_time__range=(f_date, t_date))没法包含结束日期t_date当天的所有记录——因为strptime('%Y-%m-%d')生成的t_date时间是00:00:00,而Django的__range是左闭右开区间,只会匹配到t_date零点之前的数据。
解决办法
1. 给结束日期加1天(推荐)
直接把t_date往后推一天,这样__range的右边界就变成了次日零点,自然能包含原t_date当天的所有记录:
from datetime import timedelta # ... 其他原有代码 ... t_date = datetime.datetime.strptime(to_date, '%Y-%m-%d') # 给结束日期加1天 t_date_next_day = t_date + timedelta(days=1) # 用新的范围查询 get_records_by_date = Scrapper.objects.filter(start_time__range=(f_date, t_date_next_day))
2. 拆分使用__gte和__lte
不用__range,直接明确指定时间范围:
- 如果
start_time是DateTimeField(带时间):# 把结束日期的时间设为当天最后一秒 t_date_end = t_date.replace(hour=23, minute=59, second=59) get_records_by_date = Scrapper.objects.filter( start_time__gte=f_date, start_time__lte=t_date_end ) - 如果
start_time是DateField(仅日期):# 直接用日期的大于等于和小于等于 get_records_by_date = Scrapper.objects.filter( start_time__gte=f_date.date(), start_time__lte=t_date.date() )
3. 针对日期部分过滤(DateTimeField专属)
如果只需要匹配start_time的日期部分,不管具体时间,可以用start_time__date来做查询:
get_records_by_date = Scrapper.objects.filter( start_time__date__gte=f_date.date(), start_time__date__lte=t_date.date() )
内容的提问来源于stack exchange,提问作者Ajay
相关产品推荐
相关产品推荐

