django时区如何与model.field的auto_now_add一起使用

use*_*229 26 django timezone

我想时区管理被添加到django 1.4,所以这个问题很新.

我用了一个简单的模型

class Sample(models.Model):
    ...
    date_generated = models.DateTimeField(auto_now_add = True)
Run Code Online (Sandbox Code Playgroud)

当我尝试检索新创建的记录时,它失败了.

min_datetime = datetime.now() - timedelta(seconds = 300)
sample = Sample.objects.get(date_generated__gte = min_datetime)
Run Code Online (Sandbox Code Playgroud)

并且服务器发出警告.

DateTimeField received a naive datetime (2012-06-29 15:02:15.074000) while time zone support is active.
Run Code Online (Sandbox Code Playgroud)

我找到了解决这个问题的两个方案.

  1. 在settings.py中禁用时区管理

    USE_TZ = False 
    
    Run Code Online (Sandbox Code Playgroud)

    但这并不总是令人满意的.

  2. 改变

    date_generated = models.DateTimeField(auto_now_add = True) 
    
    Run Code Online (Sandbox Code Playgroud)

    date_generated = models.DateTimeField(default=datetime.now()) 
    
    Run Code Online (Sandbox Code Playgroud)

    是时区管理工作的解决方案

Chr*_*att 22

问题出在你的最后:datetime.now()不是TZ意识到的,所以你是一个天真的TZ喂养的人.请参阅有关此问题Django文档.设置时它起作用的原因default=datetime.now是你将值强制为一个天真的日期时间,所以当你稍后将它与另一个天真的日期时间进行比较时,没有问题.

你需要通过以下方式获得"现在":

import datetime
from django.utils.timezone import utc

now = datetime.datetime.utcnow().replace(tzinfo=utc)
Run Code Online (Sandbox Code Playgroud)

  • django 1.4.5显示auto_now或auto_now_add使用timezone.now(),而不是datetime.now(),因此使用它们是安全的. (8认同)
  • 这是否意味着如果我有USE_TZ = True,我不能只使用auto_now或auto_now_add? (6认同)
  • 似乎`auto_now`和`auto_now_add`固有地使用`datetime.now`.Django似乎有点遗漏将TZ识别设施插入Django,但却错过了这个非常重要的设备,但这两个kwargs的命运已经争论了很长时间.我的理由是,他们被留下来向后兼容(并避免回击),但不要指望他们得到任何爱.如果你想要TZ识别日期时间,只需用`utcnow`设置`default` kwarg并且不要担心`auto_now`或`auto_now_add`. (5认同)
  • 从django.utils.timezone导入"现在"......的更快的方法现在导入为utcnow`.`now = utcnow()`然后会给你与@ChrisPratt给出的相同的结果. (2认同)

小智 19

使用django的timezone utils

from django.utils import timezone
date_generated = models.DateTimeField(default=timezone.now)
Run Code Online (Sandbox Code Playgroud)

  • 对于观看此主题的其他人:请注意答案如何表示`now`而不是`now()`.第二个是在加载服务器时评估,这不是你想要的. (6认同)

Cra*_*enz 9

小心设置DateTimeField默认值datetime.now(),因为当Apache/nginx加载Django时(或启动开发服务器时)将计算单个值,并且所有后续记录将接收该值.

总是因此而使用auto_now_add.

  • 只需使用不带括号的`default = datetime.now`. (20认同)