Python 按月份和日期筛选django datetime字段时出现问题

Python 按月份和日期筛选django datetime字段时出现问题,python,django,datetime,filtering,Python,Django,Datetime,Filtering,有人能给我解释一下为什么以下过滤器不能在月和日级别工作吗?按年过滤似乎有效,但其他两种方法则不行 >>> clicks.count() 36 >>> date = clicks[0].created >>> date.month 2 >>> date.year 2014 >>> date.day 1 >>> clicks.filter(created__month=2) [] >&g

有人能给我解释一下为什么以下过滤器不能在月和日级别工作吗?按年过滤似乎有效,但其他两种方法则不行

>>> clicks.count()
36
>>> date = clicks[0].created
>>> date.month
2
>>> date.year
2014
>>> date.day
1
>>> clicks.filter(created__month=2)
[]
>>> clicks.filter(created__month=02)
[]
>>> clicks.filter(created__month='02')
[]
>>> clicks.filter(created__month='2')
[]
>>> clicks.filter(created__month=date.month)
[]
>>> clicks.filter(created__day=date.day)
[]
在创建和处理queryset之前,快速更新以证明我得到了相同的行为:

>>> clicks = PreviewClick.objects.filter(created__month = 2)
>>> clicks.count()
0
>>> clicks = PreviewClick.objects.filter(created__month = 02)
>>> clicks.count()
0
>>> clicks = PreviewClick.objects.filter(created__month = '02')
>>> clicks.count()
0
>>> clicks = PreviewClick.objects.filter(created__month = '2')
>>> clicks.count()
0
这里有更多值得思考的东西:

>>> clicks = PreviewClick.objects.all()
>>> counter = 0
>>> for click in clicks:
...      if click.created.month == 2:
...           counter += 1
... 
>>> counter
35

你的语法不正确。应该是:

Clicks.objects.filter(created__month=2)

(您关闭了“对象”管理器)

我看到的行为与您完全相同

如果您检查1.6和月份查询集。他们增加了以下一段:

当USE_TZ为True时,datetime字段将在筛选之前转换为当前时区。这需要在数据库中定义时区

如果将设置中的以下行更改为False,则应开始获取预期的数据

USE_TZ = False
完美地回答了为什么它不起作用,下面是如何在不禁用django中的TZ支持的情况下实际解决它

Django文档给出了将时区定义安装到数据库的步骤:

SQLite:install
pytz
-转换实际上是在Python中执行的

PostgreSQL:无要求(参见时区)

Oracle:无要求(请参阅选择时区文件)

MySQL:安装
pytz
并使用加载时区表

在我的例子中:mysql和Mac Os,下面的命令解决了这个问题:

sudo mysql_tzinfo_to_sql /usr/share/zoneinfo/ | mysql -u root mysql

更新这里的答案,因为我遇到了上述问题,但没有一个解决方案有效。大多数新的mysql安装都预装了tz info,因此mysql_tzinfo_to_sql命令并没有真正的帮助。将TZ_INFO设置为False并不是一个真正的解决方案,因为许多人需要时区感知的日期时间

所以,对我有效的方法是创建一个tz感知的datetime对象并进行检查。假设你想过滤今天的记录,你会这样做

from datetime import datetime
import pytz

today = datetime.now().replace(tzinfo=pytz.UTC).date()   # tz aware datetime object
todays_records = myModel.objects.filter(created__year=today.year, created__month=today.month,created__day=today.day)

希望这能有所帮助。

您是如何创建点击的?您确定您有日期为2月的“已创建”的点击吗?我刚刚在我们的一个数据库上尝试了这个过滤器,它对我来说工作得很好。看起来像是你做的。objects.all(),并将其分配给单击,然后尝试对其进行过滤。您可能想执行.objects.filter(..)@user590028在第二行,我获取了queryset中第一项的实际“创建”值,并演示了月份值实际上是二月。所以过滤器应该至少有一条记录,对吗?你能告诉我们,
PreviewClick.objects.all()
中有一个月为2的对象吗?我想我没有指定点击是我在2014年之前已经得到的查询集。all()或过滤,这似乎有效。filter()函数的工作原理应该相同。在任何情况下,在创建queryset.Hmmm…之前,我都会更新问题以证明我得到了相同的结果。我试试看会发生什么。我想我对处理时区还不熟悉——我正在尝试根据时区等进行正确过滤,尽管我只对实际的数据库记录使用UTC。我一直在视图中计算时区。如果我以这种方式处理它,我不需要使用_TZ吗?我担心我没有处理时区,而且我当前的项目也不需要处理时区,所以我目前的修复对我来说已经足够了。我希望这些信息为您提供了使代码重新工作所需的信息。事实上,这应该是正确的答案。几乎每个项目都应该使用时区识别日期。