Иногда, в процессе работы с датами и фильтрации объектов возникает довольно неприятное предупреждение:
RuntimeWarning: DateTimeField Object.updated_at received a naive datetime (2020-05-05 18:02:41.675117) while time zone support is active.
Это предупреждение не останавливает выполнение скрипта, просто можно получить не совсем коректные данные в результате фильтрации.
Как исправить naive datetime?
Чтобы решить эту проблему и получить более достоверные данные, достаточно использовать пакет pytz.
Рассмотрим ситуацию. Допустим, мы хотим отфильтровать все объекты, которые изменились за последние 5 минут.
Пример, в котором мы получаем предупреждение:
import datetime from app.models import TestObject last_5_mins = datetime.datetime.now() - datetime.timedelta(minutes=5) qs = TestObject.objects.filter(updated_at__gte=last_5_mins )
Используя pytz мы укажем коректный часовой пояс:
import datetime import pytz from app.models import TestObject OurTZ = pytz.timezone('Europe/Kiev') last_5_mins = datetime.datetime.now(OurTZ) - datetime.timedelta(minutes=5) qs = TestObject.objects.filter(updated_at__gte=last_5_mins )
Теперь все хорошо, проблемы нет. Мы указали, что нужно использовать киевское время.
Naive datetime и Django. Почему так происходит?
Вызов функции datetime.now() иденичен datetime.now(tz=None) или datetime.today(). Документация: https://docs.python.org/3/library/datetime.html#datetime.datetime.now.
Все дело в том, что когда в Django включена поддержка часовых поясов, информация в БД о дате и времени храниться в формате UTC.
При этом, система использует данные в UTC, а пользователю в интерфейсе транслирует все в том часовом поясе, в котором он находиться.
Поддержка часовых поясов по умолчанию отключена. Чтобы ее включить, в settings.py указываем:
USE_TZ = TrueDjango использует pytz для работы с датами при включеной поддержке часовых поясов.
Модуль django.utils.timezone предоставляет функцию now(), которая возвращает текущее время в зависимости от значения параметра конфигурации USE_TZ.
Читаем справку: docs.djangoproject.com/timezones/#interpretation-of-naive-datetime-objects.