Подтвердить что ты не робот

Как работает часовой пояс django с model.field auto_now_add

Я полагаю, что управление часовым поясом было добавлено к 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.

Я выяснил два решения этой проблемы.

  • Отключить управление часовым поясом в settings.py

    USE_TZ = False 
    

    но это не всегда желательно.

  • изменения

    date_generated = models.DateTimeField(auto_now_add = True) 
    

    к

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

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

4b9b3361

Ответ 1

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

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

import datetime
from django.utils.timezone import utc

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

Ответ 2

Использовать часовые пояса django

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

Ответ 3

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

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