Django按日期范围过滤但不包括年份
Posted
技术标签:
【中文标题】Django按日期范围过滤但不包括年份【英文标题】:Django filter by date range but exclude the year 【发布时间】:2021-11-01 05:50:15 【问题描述】:我知道如果我想按日期范围过滤结果,我只需使用类似
Sample.objects.filter(birthday__range=(start_date, end_date))
但是如何按不包括年份的日期范围进行过滤?
【问题讨论】:
想象start_date
是 2020 年 12 月,end_date
是 2021 年 8 月,这是否意味着 12 月和 8 月之间的每个日期,所以只剩下 9 月、10 月和 11 月?
是的。例如,您将如何查看用户的生日是否在上个月或其他日期。
【参考方案1】:
我们可以使用以下日期时间范围:
from datetime import timedelta
from django.db.models import Q
def filter_query(start_date, end_date):
a = am, ad = start_date.month, start_date.day
b = bm, bd = end_date.month, end_date.day
end_date2 = end_date + timedelta(days=1)
c = end_date2.month, end_date2.day
if c == (2, 29) and a == (3, 1):
return ~Q(birthday__month=2, birthday__day__gt=28)
if a == c:
return Q()
if a <= b:
if am == bm:
return Q(birthday__month=am, birthday__day__range=(ad, bd))
else:
return (Q(birthday__month=am, birthday__day__gte=ad) |
Q(month__range=(am+1, bm-1)) |
Q(birthday__month=bm, birthday__day__lte=bd))
else:
return ~filter_query(end_date+timedelta(days=1), start_date-timedelta(days=1))
这将返回一个Q
对象,然后可以通过过滤查询集来使用该对象,例如:
Sample.objects.filter(<strong>filter_query(</strong>date(2020, 12, 15), date(2021, 1, 16)<strong>)</strong>)
基本上有五种情况:
如果end_date
是 2 月 28 日,开始日期是 3 月 1 日,那么我们排除 2 月 29 日。
如果end_date
加一天与开始日期相同,那么我们就不用过滤了;
如果start_date
小于end_date
并且月份匹配,那么我们过滤该月份,并检查日期范围;
如果start_date
小于end_date
并且月份不匹配,那么我们查找范围:
具有相同月份 start_date
且日期大于 start_date
月份的项目;
在start_date
的下个月和end_date
的上个月之间的月份的项目;和
与end_date
相同月份且日期小于或等于end_date
日期的项目。
如果结束日期小于开始日期,那么我们返回一个否定的 end_date
加一天,start_date
减一天。
【讨论】:
【参考方案2】:您可以同时使用过滤器和排除。像你一样过滤,然后排除年份,比如 2021
Sample.objects.filter(birthday__range=(start_date, end_date)).exclude(birthday_date__year=2021)
【讨论】:
以上是关于Django按日期范围过滤但不包括年份的主要内容,如果未能解决你的问题,请参考以下文章