Django:时区支持处于活动状态时的天真日期时间(sqlite)
Posted
技术标签:
【中文标题】Django:时区支持处于活动状态时的天真日期时间(sqlite)【英文标题】:Django: Naive datetime while time zone support is active (sqlite) 【发布时间】:2014-12-03 14:48:21 【问题描述】:我正在绕圈子,需要一些帮助。我继续收到naive timezone
警告。不知道我做错了什么!精氨酸。
这里是警告:
/django/db/models/fields/__init__.py:1222: RuntimeWarning: DateTimeField Video.modified received a naive datetime (2014-10-07 00:00:00) while time zone support is active.
RuntimeWarning)
这是模型代码(有所删节):
from django.db import models
from django.utils import timezone
class ItemBase(models.Model):
created = models.DateTimeField(editable=False)
modified = models.DateTimeField(editable=False)
class Meta:
abstract = True
def save(self, *args, **kwargs):
"""Updates timestamps on save"""
if not self.id:
self.created = timezone.now()
self.modified = timezone.now()
return super(ItemBase, self).save(*args, **kwargs)
class Video(ItemBase):
pass
以及我的设置文件的相关(我认为)部分:
TIME_ZONE = 'UTC'
USE_TZ = True
这是一个 sqlite 问题吗(仍在测试中)?还是我在这里遗漏了一些基本的东西?我已经阅读了here 和here,当然还有文档here。但我很难过。谢谢。
编辑:添加了引发错误的测试
我在运行测试时遇到了错误……我把编辑过的东西留在了那里,但你应该明白了:
from django.test import TestCase
from django.contrib.auth import get_user_model
from video.models import Video, VideoAccount
class VideoTestCase(TestCase):
def setUp(self):
user = get_user_model().objects.create_user(
username='jacob', email='jacob@test.com', password='top_secret')
self.video_account = VideoAccount.objects.create(
account_type=1, account_id=12345, display_name="Test Account" )
self.pk1 = Video.objects.create(video_type=1, video_id="Q7X3fyId2U0",
video_account=self.video_account, owner=user)
def test_video_creation(self):
"""Creates a video object"""
self.assertEqual(self.pk1.video_id, "Q7X3fyId2U0")
self.assertEqual(self.pk1.video_link, "https://www.youtube.com/watch?v=Q7X3fyId2U0")
【问题讨论】:
收到此错误时 @HasanRamezani 当我在我的测试套件中创建一个新模型时 - 对不起,我想我应该包括那个......我可以在底部添加它! ...而且,当我使用管理员添加时,我在开发服务器中看不到该警告...仅在运行测试时。 删除USE_TZ = True
,这可能会解决您的问题。
@HasanRamezani - 它确实消除了警告,但我想要时区支持!所以我的问题还没有解决。微笑。
您发布的内容看起来不错,所以问题一定出在其他地方。既然您说它只发生在测试中,请尝试使用TransactionTestCase
而不是TestCase
。没关系,但 TTC 通常更安全。发布您未编辑的模型代码,以及您正在运行的确切测试命令。您有多个设置文件吗?
【参考方案1】:
所以我终于想通了,感谢大家的意见,让我以正确的方式思考:
我过去的一次迁移将datetime.date.today()
作为默认值(这是迁移给出的提示)。我没有考虑这一点,因为当时我什至在模型中没有任何数据,然后,即使该迁移已再次迁移(更进一步),似乎测试系统正在运行每次迁移每次开始。所以:收到了警告。
更新:这应该是fixed in 1.7.1。
【讨论】:
【参考方案2】:您使用的是 SQLite 数据库,而 SQlite db 不支持时区。这导致了警告。
可以通过使用不同的数据库后端来删除此警告。
如果您想使用 sqlite,可能将这些行放在设置文件中会有所帮助:
import warnings
import exceptions
warnings.filterwarnings("ignore", category=exceptions.RuntimeWarning, module='django.db.backends.sqlite3.base', lineno=53)
【讨论】:
感谢您的评论-我认为它可能是 sqlite 但是当我发现 sn-p (包括在内)时,它并没有抑制对我的警告。这就是为什么我认为它可能是别的东西......我已将它添加到我的settings.py
文件中,但没有运气!
这是不正确的。数据库不需要支持时区,因为当USE_TZ = True
时,日期时间总是以UTC 格式存储。 Aware datetimes 和 SQLite 可以很好地协同工作。
@KevinChristopherHenry: docs(sqlite.org/datatype3.html) SQLite 没有专门用于存储日期和/或时间的存储类。相反,SQLite 的内置日期和时间函数能够将日期和时间存储为 TEXT、REAL 或 INTEGER 值。还有错误:: RuntimeWarning: DateTimeField Video.modified 在时区支持处于活动状态时收到了一个天真的日期时间 (2014-10-07 00:00:00)...当 django 尝试从 SQLite db 读取字段值时,它会获取字符串没有 tz 信息(更多参考:groups.google.com/forum/#!topic/django-developers/duK0htVhq3k)
我没有说 SQLite 支持时区,我说它不需要需要支持时区,因为日期时间在存储之前被标准化为 UTC。至于该消息线程,它已有三年多的历史,并且早于时区支持的引入。如果您需要更多证据,请注意SQLite-specific documentation 没有提到任何缺乏对已知日期时间的支持。
@KevinChristopherHenry 我认为这与测试系统有关;如果我在shell
中运行相同系列的命令,我没有得到任何RuntimeWarning
... 不知道该怎么做,但我觉得至少可以说令人讨厌!【参考方案3】:
你安装http://pytz.sourceforge.net/了吗?
激活时区支持后,Django 需要定义默认时区。当 pytz 可用时,Django 从 tz 数据库加载这个定义。这是最准确的解决方案。否则,它依赖于操作系统报告的本地时间和 UTC 之间的差异来计算转换。这不太可靠,尤其是在 DST 转换时。
【讨论】:
谢谢 - 是的,无论有无……我都试过了,但似乎都没有什么不同。以上是关于Django:时区支持处于活动状态时的天真日期时间(sqlite)的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 RuntimeWarning:DateTimeField 在时区支持处于活动状态时收到天真> datetime?