2012-06-29 2 views
18

Я полагаю, что управление часовым поясом было добавлено к django 1.4, поэтому проблема довольно новая.Как работает часовой пояс django с auto_now_add model.field

Я использовал простую модель

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 
    

    , но это не всегда desierable.

  2. изменения

    date_generated = models.DateTimeField(auto_now_add = True) 
    

    в

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

    это решение, которое поддерживает управление часового пояса работая

ответ

17

проблема на вашем конце: datetime.now() не TZ известно, так что вы тот, кто питается наивным TZ. См. Django docs on this issue. Причина, по которой она работает при установке default=datetime.now, заключается в том, что вы вынуждаете значение наивному дат-времени, поэтому, когда вы позже сравниваете его с другим наивным datetime, нет проблем.

Вы должны получить «сейчас» следующим образом:

import datetime 
from django.utils.timezone import utc 

now = datetime.datetime.utcnow().replace(tzinfo=utc) 
+6

Означает ли это, я не могу просто использовать auto_now или auto_now_add, если у меня есть USE_TZ = True? – dannyroa

+5

Кажется, 'auto_now' и' auto_now_add' по своей сути используют 'datetime.now'. Кажется странным упущением со стороны Django, чтобы вставить средства TZ в Django, но пропустить этот довольно важный, но судьба этих двух kwargs обсуждалась в течение длительного времени. Мое рассуждение состоит в том, что их оставляют для обратной совместимости (и избегать отталкивания), но не ожидайте, что они получат любовь. Просто установите 'default' kwarg с' utcnow' и не волнуйтесь о 'auto_now' или' auto_now_add', если вы хотите знать время от времени TZ. –

+0

Спасибо, Крис. Я не думаю, что «default» будет работать при замене «auto_now», хотя последний всегда обновляет время для каждого сохранения, а «default» - только тогда, когда поле не имеет значения. – dannyroa

7

Будьте осторожны, устанавливая значение по DateTimeField умолчанию datetime.now(), как будет вычислять одно значение, когда Apache/Nginx нагрузки Джанго (или при запуске сервер разработки), и все последующие записи получат это значение.

По этой причине всегда используйте auto_now_add.

+13

Просто используйте 'default = datetime.now' без скобок. –

13

Использование часовых поясов Utils Джанго

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

Для просмотра другой темы: обратите внимание, как ответ говорит 'now', а не' now() '. Второй будет оценивать при загрузке сервера, чего вы не хотите. – Pieter

Смежные вопросы