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?

抑制 django 天真的日期时间警告

Django:查询时的天真日期时间

Django 中 DateField 的 RuntimeWarning

Django 日期时间查询