Django:按日期过滤日期时间忽略时间

Posted

技术标签:

【中文标题】Django:按日期过滤日期时间忽略时间【英文标题】:Django: datetime filter by date ignoring time 【发布时间】:2018-01-25 20:33:13 【问题描述】:

我正在尝试过滤在某一天安排的Matches。我不能这样做:

match_queryset.filter(start=date)

因为它也会按时间过滤,但我可以这样做:

match_queryset.filter(start__year=a_date.year, start__month=a_date.month, start__day=a_date.day)

但这太复杂了,我觉得可以有更简单的方法。

那我也可以使用范围:

t0 = datetime.datetime.combine(a_date, datetime.time(0, 0))
t1 = datetime.datetime.combine(a_date, datetime.time(23, 59, 59))
match_queryset.filter(start__gte=t0, start__lte=t1)

但这似乎有点矫枉过正,它可能会产生低效的查询。

我不能只查询实际日期吗?比如:

# this of course doesn't work
match_queryset.filter(start__date=date)

不用说我已经尝试过寻找解决方案但找不到任何解决方案。

【问题讨论】:

见***.com/a/1973917/2689986 @AshishNitinPatil 这实际上是我的第二个解决方案 我在这句话中提到了它:因为它非常冗长,所以计划使用__date 运算符改进语法。详情请查看“#9596 Comparing a DateTimeField to a date is too hard”。 @AshishNitinPatil 从 2009 年开始,他们还没有实现 __date 为什么不添加DateField 【参考方案1】:

从 Django 1.9 开始,您可以使用 __date field lookup,正如您在问题中提到的那样。对于旧版本,您将不得不使用其他方法。

例如

Entry.objects.filter(start__date=datetime.date(2005, 1, 1))
Entry.objects.filter(start__date__gt=datetime.date(2005, 1, 1))

【讨论】:

【参考方案2】:

如果您不能使用__date 过滤器,我认为最干净的方法是这样做:

from datetime import datetime, timedelta

d = datetime.now()  # or whatever you want

match_queryset.filter(start__gte=d.date(), start__lt=d.date()+timedelta(days=1))

如果你在 Django 的settings.py 中有USE_TZ=True,你会收到警告:

RuntimeWarning: DateTimeField (...) received a naive datetime (...) while time zone support is active.

但过滤器仍然可以工作。将在 Django 的时区进行比较(TIME_ZONE 来自settings.py),至少我是这样。

【讨论】:

以上是关于Django:按日期过滤日期时间忽略时间的主要内容,如果未能解决你的问题,请参考以下文章

Django rest框架按日期时间过滤

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

Django:按日期范围过滤对象

Django - 如何使用 Django Rest Framework 按日期过滤?

Django按日期范围过滤但不包括年份

Django - 按最大(日期)年份过滤查询集