Я сделал то, что хотел, определив пользовательскую функцию базы данных, которая преобразует поле даты и времени в часовой пояс, который также определен в соответствующем столбце. Теперь работает только с postgres (используя выражение «в часовом поясе»), но может быть обновлен для использования других механизмов БД, также используя их функции преобразования часового пояса.
из django.db.models import Func, DateTimeField
class ConvertToTimezone(Func):
"""
Custom SQL expression to convert time to timezone stored in database column
"""
output_field = DateTimeField()
def __init__(self, datetime_field, timezone_field, **extra):
expressions = datetime_field, timezone_field
super(ConvertToTimezone, self).__init__(*expressions, **extra)
def as_sql(self, compiler, connection, fn=None, template=None, arg_joiner=None, **extra_context):
params = []
sql_parts = []
for arg in self.source_expressions:
arg_sql, arg_params = compiler.compile(arg)
sql_parts.append(arg_sql)
params.extend(arg_params)
return "%s AT TIME ZONE %s" % tuple(sql_parts), params
И вот как я его использую:
Session.objects.annotate(created_local=ConvertToTimezone('created', 'place__timezone')).filter(created_local__hour=10)
Я не очень хорошо понимаю, как работают функции базы данных Django и выражения базы данных, поэтому я рад (и будубудьте готовы услышать) любые отзывы / улучшения к решению