【问题标题】:Django filter by date range but exclude the yearDjango按日期范围过滤但不包括年份
【发布时间】: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 月?
  • 是的。例如,您将如何查看用户的生日是否在上个月或其他日期。

标签: python django date-range


【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 2014-09-04
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      相关资源
      最近更新 更多