我正在尝试在 Django 中编写一个自定义 PostgreSQL 函数,它将强制日期时间为查询集中指定的时区。我对 db 函数的第一次调用如下所示:
from django.db.models.expressions import Func
class DateTimeInTimezone(Func):
template="%(expressions)s AT TIME ZONE %(tz_info)s"
Run Code Online (Sandbox Code Playgroud)
该函数适用于简单的情况,我直接将时区字符串传递到函数中,如下所示:
MyModel.objects.filter(timefield__gte=DateTimeInTimezone(Now(), tz_info='EST'))
Run Code Online (Sandbox Code Playgroud)
但是,它不适用于更复杂的情况,即时区是在模型的某些字段上定义的。考虑以下人为的示例:
class User(models.Model):
time_zone = models.CharField()
class Meeting(models.Model):
users = models.ManyToManyField(User, related_name='meetings')
start_time = models.DateTimeField() # in UTC
end_time = models.DateTimeField() # in UTC
Run Code Online (Sandbox Code Playgroud)
要回答“今天当地时间中午 12 点哪些用户将参加会议?”这一问题,我需要此查询集的一些变体:
noon_utc = ...
User.objects.filter(
meetings__start_time__lte=DateTimeInTimezone(noon_utc, tz_info=F('time_zone')),
meetings__end_time__gt=DateTimeInTimezone(noon_utc, tz_info=F('time_zone'))
)
Run Code Online (Sandbox Code Playgroud)
然而,按照目前的编写,DateTimeInTimezone将只是将字符串注入F('time_zone')到 sql 中,而不是解析该字段。
是否可以向此函数添加对F 表达式的支持?我还应该考虑其他方法吗?
django django-orm django-queryset django-postgresql django-1.10