我正在使用启用了mysql和timezones的django 1.4.1。我向yaml做了转储数据,修改了一些字段来创建一些测试数据,并试图将其重新加载。但是,即使指定了tz,Django也会抱怨天真的日期时间
具体来说,我的loaddata有:
fields: {created_date: !!timestamp '2012-09-15 22:17:44+00:00', ...
但loaddata给出错误:
RuntimeWarning: DateTimeField received a naive datetime (2012-09-15 22:17:44) while time zone support is active.
这对我来说没有多大意义,看作是:
有什么方法可以告诉django这是一个UTC日期吗?
答案 0 :(得分:21)
问题源于PyYAML。当loaddata将日期时间移交给PyYAML时,它需要知道日期时间,将时间调整为UTC,然后返回一个天真的日期时间,从而生成警告。
有一个Django ticket,以及有关该问题的PyYAML ticket。两者都涉及上述意外行为的更多细节。从门票中的评论来看,这个问题似乎不太可能很快得到解决。
您是否在项目的settings.py中设置TIME_ZONE = 'UTC'
,您将在正确的时间加载,但仍会收到警告。如果你的时区被设置为其他任何东西,Django会将日期时间视为本地时间,并将其调整为UTC,这可能是不受欢迎的。
避免这种情况的最佳方法是使用JSON作为序列化格式。
希望有所帮助。
答案 1 :(得分:8)
来自docs ...
序列化感知日期时间时,包括UTC偏移量,如 这样:
"2011-09-01T13:20:30+03:00"
对于一个天真的日期时间,它显然不是:
"2011-09-01T13:20:30"
...而不是......
created_date: !!timestamp '2012-09-15 22:17:44+00:00'
... ... ...
created_date: '2012-09-15T22:17:44+00:00'
...或...
created_date: '2012-09-15T22:17:44Z'
......会奏效。
答案 2 :(得分:1)
您可以将django / core / serializers / pyyaml.py复制到您的项目目录, 并替换以下代码(在ver.1.9.9的情况下可能是78-79行)
for obj in PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options):
yield obj
到
output = yaml.load(stream, Loader=SafeLoader)
for a_model in output:
for key, value in a_model.items():
if key == 'fields':
for vkey, vvalue in value.items():
if isinstance(vvalue, datetime.datetime):
value[vkey] = vvalue.replace(tzinfo=pytz.utc)
for obj in PythonDeserializer(output, **options):
yield obj
当然pytz已经安装并且
import pytz
是必需的。
此代码会将所有天真的日期时间值转换为UTC感知。
要覆盖默认序列化程序,请在settings.py中添加SERIALIZATION_MODULES:
SERIALIZATION_MODULES = {'yaml': 'yourproj.pyyaml'}
我希望这个猴子补丁工作正常。
答案 3 :(得分:0)
我想继续使用YAML而不是JSON固定装置,因此我可以在数据中添加注释。这里的解决方法为我解决了这个问题:https://code.djangoproject.com/ticket/18867
即,手动更改YAML固定装置,使其:
...而且显然触发了Django的时间戳解析逻辑,而不是损坏的PyYAML逻辑。