【发布时间】: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。 -
凯文,感谢您的有用评论。在这种情况下,创建自定义模型字段比我们想要进行的更改要多一些,但我可以看到这将是一种合理的方法。您的其他帖子也有很好的建议。