【问题标题】:Is there a way for Django to accept naive datetimes with USE_TZ=True, or to suppress warnings?Django 有没有办法接受 USE_TZ=True 的幼稚日期时间,或者抑制警告?
【发布时间】:2020-03-13 07:00:25
【问题描述】:

我们公司是 Django 的长期用户——超过 10 年。我们目前正在运行 Django 1.11.26。多年来,我们处理了很多与日期时间相关的问题,但事实证明我们当前的问题具有挑战性。

我们的目标是做到以下几点:

  • 使用 Django 的时区支持(设置 USE_TZ=True),并将 UTC 作为默认时区
  • 对于几个非规范化字段(能源数据的每日汇总)存储原始日期时间

正如许多 Stack Overflow 问题中所记录的,Django 将发出警告,并将日期时间字段值设置为天真的日期时间: RuntimeWarning:DateTimeField 收到一个简单的日期时间...而时区支持处于活动状态。

我们认为我们存储原始日期时间的用例是合理的。虽然对于我们几乎所有的日期时间字段,使用 UTC 是有意义的,但对于某些类型的每日汇总,我们希望存储一个幼稚/不可知的日期时间,指示当地时区中一天的开始日期时间(不同对象的多个时区)。通过使用简单的日期时间,我们可以使用与日期时间相关的过滤器。因此,如果我们要汇总给定日期时间的某些类型的能量汇总,我们可以通过在那个天真的本地日期时间上以各种方式过滤,找到任何时区(洛杉矶、芝加哥、波士顿)的建筑物的相同本地日期时间的汇总。

以下是我们尝试过的一些方法:

  • 将本地/原始日期时间保存为具有给定本地时区的感知日期时间。这不起作用,因为 Django 将始终转换为等效的 UTC。我们可以理解为什么会发生这种情况,部分原因是 MySQL 5.6 DATETIME 字段不支持时区。
  • 使用 override_settings(USE_TZ=False) 覆盖汇总模型的保存方法。这确实抑制了关于天真的日期时间的运行时警告,但它强制模型中的所有日期时间都保存为天真。而且它看起来很老套,因为 override_settings 是用于测试的。

我们现在唯一的解决方法是告诉 Django 这个 local/naive datetime 字段是 UTC —— 所以保存时不会进行时间转换,也不会发出运行时警告,因为它是一个可感知的日期时间。但它最终是错误的。这些不是 UTC 日期时间。它们是故意天真的、非规范化的日期时间。而且我们担心这可能会影响我们,尤其是随着 Django 不断发展其时区支持。

对于这个问题,我们还没有考虑过其他可能的解决方案吗?提前感谢您考虑这个问题。

【问题讨论】:

  • 一种解决方案是创建一个custom model field,继承自DateTimeField,通过在转换期间添加或删除UTC 来存储原始日期时间。这应该避免警告,并且比您上面提到的解决方法更好,因为您的应用程序代码将使用天真的日期时间。另见我的回答here
  • 凯文,感谢您的有用评论。在这种情况下,创建自定义模型字段比我们想要进行的更改要多一些,但我可以看到这将是一种合理的方法。您的其他帖子也有很好的建议。

标签: django django-timezone


【解决方案1】:

要过滤或抑制警告,您可以使用warnings.filterwarnings

您可以尝试在 settings.py 中添加类似的内容来过滤警告:

from warnings import filterwarnings
filterwarnings('ignore', message=r'.*received a naive datetime')

您可能需要调整filterwarnings 调用以根据需要抑制警告。

【讨论】:

  • 感谢您的建议。这似乎是目前最实用的解决方案,并且对我们有用。为了针对应该接受天真的日期时间的特定字段,我们确实摆弄了正则表达式——所以如果其他字段引用了天真的日期时间,我们仍然可以收到运行时警告。
猜你喜欢
  • 2015-01-02
  • 2010-09-16
  • 2012-10-10
  • 2021-06-11
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 2023-04-05
  • 2019-11-07
相关资源
最近更新 更多