J'essaye d'écrire une fonction PostgreSQL personnalisée dans Django qui va coercer les dates-heures dans un fuseau horaire spécifié à l'intérieur d'un ensemble de requêtes. Ma première passe à la fonction db ressemble à ceci:DjangoORM: Résolution de l'expression F dans la fonction de base de données personnalisée
from django.db.models.expressions import Func
class DateTimeInTimezone(Func):
template="%(expressions)s AT TIME ZONE %(tz_info)s"
Cette fonction fonctionne dans le cas simple où je passe une chaîne de fuseau horaire dans la fonction directement comme ceci:
MyModel.objects.filter(timefield__gte=DateTimeInTimezone(Now(), tz_info='EST'))
Cependant, il ne travailler dans le cas le plus complexe, où le fuseau horaire est défini sur un champ du modèle. Prenons l'exemple suivant artificiel:
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
Pour répondre à la question « Qu'est-ce que les utilisateurs seront à une réunion à 12 h aujourd'hui, heure locale? », Je aurais besoin une certaine variation de cette queryset:
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'))
)
Comme actuellement écrit, cependant, DateTimeInTimezone
injectera simplement la chaîne F('time_zone')
dans le sql plutôt que de résoudre le champ.
Est-il possible d'ajouter le support pour F Expressions à cette fonction? Y a-t-il une autre approche que je devrais envisager?
Hé, c'est génial! Merci d'avoir suggéré cette solution. J'ai fait de votre réponse la réponse acceptée car il est définitivement préférable de corriger les singes (comme vous l'avez mentionné dans votre commentaire). – chukkwagon