Как я могу привести DateField() + TimeField() к местному времени в Django QuerySet?

Моя модель имеет такие поля:

  • дата = models.DateField()
  • start_time = models.TimeField()
  • >end_time = models.TimeField()

Я хотел бы аннотировать набор запросов с помощью start_datetime и end_datetime, например, так:

class SessionQuerySet(models.QuerySet):
    def with_datetimes(self):
        return self.annotate(
            start_datetime=ExpressionWrapper(
                F('date') + F('start_time'),
                output_field=models.DateTimeField()
            ),
            end_datetime=ExpressionWrapper(
                F('date') + F('end_time'),
                output_field=models.DateTimeField()
            ),
        )

Однако, поле вывода в запросе приводит к наивному datetime:

>>> Session.objects.with_datetimes()[0].start_datetime
<<< datetime.datetime(2021, 9, 20, 17, 0)

Я пробовал обернуть вышеприведенные выражения в django.db.models.functions.Cast(), с output_field=DateTimeField(), но это приводит к UTC, а не к местному часовому поясу.

По сути, мне нужен эквивалент функции Postgres at time zone для преобразования наивного времени в локальное. Есть ли способ сделать это в Django?

Думаю, вы можете использовать библиотеку pytz (https://pypi.org/project/pytz/) для локализации наивного datetime.

from datetime import datetime
from pytz import timezone

tz = timezone('Europe/Amsterdam')
naive_dt = datetime(2021, 9, 20, 17, 0)
localized_dt = tz.localize(naive_dt)
print(localized_dt)
Вернуться на верх