【问题标题】:How django time zone works with model.field's auto_now_adddjango 时区如何与 model.field 的 auto_now_add 一起使用
【发布时间】:2012-07-01 01:07:11
【问题描述】:

我想 Django 1.4 中添加了时区管理,所以这个问题是相当新的。

我使用了一个简单的模型

class Sample(models.Model):
    ...
    date_generated = models.DateTimeField(auto_now_add = True)

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

min_datetime = datetime.now() - timedelta(seconds = 300)
sample = Sample.objects.get(date_generated__gte = min_datetime)

服务器发出警告。

DateTimeField received a naive DateTime (2012-06-29 15:02:15.074000) while time zone support is active.

我想出了两个解决这个问题的办法。

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

     USE_TZ = False 
    

但这并不总是可取的。 2.改变

    date_generated = models.DateTimeField(auto_now_add = True) 

    date_generated = models.DateTimeField(default=datetime.now()) 

是保持时区管理正常工作的解决方案

【问题讨论】:

    标签: django timezone


    【解决方案1】:

    使用 django 的时区工具

    from django.utils import timezone
    date_generated = models.DateTimeField(default=timezone.now)
    

    【讨论】:

    • 对于查看此线程的其他人:请注意答案是 now 而不是 now()。第二个会在加载服务器时进行评估,这不是您想要的。
    【解决方案2】:

    问题出在你的头上:datetime.now() 不知道 TZ,所以你是一个在天真的 TZ 中喂养的人。请参阅Django docs on this issue。设置default=datetime.now 时它起作用的原因是您将值强制为天真的日期时间,因此当您稍后将其与另一个天真的日期时间进行比较时,没有问题。

    您需要通过以下方式获得“现在”:

    import datetime
    from django.utils.timezone import utc
    
    now = datetime.datetime.utcnow().replace(tzinfo=utc)
    

    【讨论】:

    • 这是否意味着我不能只使用 auto_now 或 auto_now_add 如果我有 USE_TZ = True?
    • 似乎auto_nowauto_now_add 天生就使用datetime.now。将 TZ 感知设施插入 Django 似乎是 Django 的一个奇怪的遗漏,但却错过了这个非常重要的设施,但这两个 kwargs 的命运已经争论了很长时间。我的理由是它们被保留是为了向后兼容(并避免推回),但不要指望它们会得到任何爱。只需将default kwarg 设置为utcnow,不要担心auto_nowauto_now_add,如果你想知道TZ 的日期时间。
    • 谢谢克里斯。我不认为“默认”可以代替“auto_now”,因为后者总是更新每次保存的时间,而“默认”仅在字段没有值时。
    • 获得“现在”的更快方法...from django.utils.timezone import now as utcnow。然后now = utcnow() 会给你和@ChrisPratt 一样的结果。
    • django 1.4.5 显示 auto_now 或 auto_now_add 使用 timezone.now() ,而不是 datetime.now() 所以使用它们是安全的。
    【解决方案3】:

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

    因此,请始终使用auto_now_add

    【讨论】:

    • 只使用default=datetime.now,不带括号。
    【解决方案4】:

    在您的 Django 模型中: 从settings.py 导入 TIME_ZONE date_field = models.DateTimeField(default=datetime.now(pytz.timezone(TIME_ZONE)))

    【讨论】:

    • 这将在 django 加载时计算并且不再更新
    猜你喜欢
    • 2014-11-28
    • 2021-04-20
    • 2011-08-19
    • 2020-05-18
    • 2019-10-11
    • 2018-09-27
    • 2010-12-16
    • 2013-06-30
    • 2011-09-19
    相关资源
    最近更新 更多