按月和日过滤 django 日期时间字段的问题
Posted
技术标签:
【中文标题】按月和日过滤 django 日期时间字段的问题【英文标题】:Problems filtering django datetime field by month and day 【发布时间】:2014-03-22 01:04:58 【问题描述】:谁能向我解释为什么以下过滤器在月和日级别不起作用?按年份过滤似乎有效,但其他两个无效。
>>> 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)
[]
快速更新以证明我在创建和处理查询集之前得到了相同的行为:
>>> 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
【问题讨论】:
你是如何创造点击的? 您确定您的点击日期为 2 月吗?我刚刚在我们的一个数据库上尝试了这个过滤器,对我来说效果很好。 看起来你做了PreviewClick.objects.all()
里面有一个2个月的对象
【参考方案1】:
我看到的行为与您完全相同。
如果您检查 documentation 的 1.6 和月份查询集。他们添加了以下段落:
“当 USE_TZ 为 True 时,日期时间字段在过滤前转换为当前时区。这需要在数据库中定义时区。”
如果您将设置中的以下行更改为 False,那么您应该开始获取您期望的数据。
USE_TZ = False
【讨论】:
嗯....有趣。我会试试这个,看看会发生什么。我想我是处理时区的新手——我正在尝试根据时区等进行正确过滤,尽管我只将 UTC 用于实际的数据库记录。我一直在视图中进行时区计算。如果我这样处理,我不需要 USE_TZ 吗? 恐怕我还没有处理时区问题,我目前的项目也不需要,所以目前我的解决方案对我来说已经足够了。我希望这些信息已经为您提供了让您的代码再次运行所需的信息。【参考方案2】:@Simon Wilder 完美回答了为什么它不起作用,这里是你如何在不禁用 django 中的 TZ 支持的情况下实际解决它
Django 文档给出instruction 将时区定义安装到数据库:
SQLite:安装
pytz
— 转换实际上是在 Python 中执行的。PostgreSQL:无要求(参见时区)。
Oracle:无要求(请参阅选择时区文件)。
mysql:安装
pytz
并使用mysql_tzinfo_to_sql
加载时区表。
在我的例子中:mysql 和 Mac Os,下面的命令解决了这个问题:
sudo mysql_tzinfo_to_sql /usr/share/zoneinfo/ | mysql -u root mysql
【讨论】:
确实这应该是正确的答案。几乎每个项目都应该使用时区感知日期。【参考方案3】:您的语法不正确。应该是:
Clicks.objects.filter(created__month=2)
(您离开了“对象”管理器)
【讨论】:
我想我没有指定 clicks 是我已经使用 .all() 或在 2014 年过滤的查询集,这似乎有效。 filter() 函数应该是一样的。在任何情况下,我都会更新问题以证明在创建查询集之前我得到了相同的结果。【参考方案4】:因为我遇到了上述问题,所以在这里更新答案,但没有一个解决方案有效。大多数新的 mysql 安装都预装了 tz-info,因此 mysql_tzinfo_to_sql 命令不会真正有帮助。并且将 TZ_INFO 设置为 False 并不是真正的解决方案,因为许多人需要时区感知日期时间。
所以,对我有用的是创建一个 tz 感知日期时间对象并检查它。假设你想过滤今天的记录,你会做类似的事情,
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)
希望这会有所帮助。
【讨论】:
以上是关于按月和日过滤 django 日期时间字段的问题的主要内容,如果未能解决你的问题,请参考以下文章
Drupal 视图 UI,过滤器暴露,集合字段内容中的日期仅按月和年(无天)