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按日期范围过滤但不包括年份的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 中按日期范围过滤记录?

Django:按日期范围过滤对象

DataTables+Datepicker 按日期范围过滤表格

Google Dashboard 过滤器折线图(按年份)

在 Django admin 中按自定义日期范围过滤

Yii2 GridView 按年份过滤日期