My model as these fields:
models.DateField()
models.TimeField()
models.TimeField()
I would like to annotate the queryset with start_datetime
and end_datetime
, like so:
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()
),
)
However, the output field in the query results in a naive datetime:
>>> Session.objects.with_datetimes()[0].start_datetime
<<< datetime.datetime(2021, 9, 20, 17, 0)
I would like the dates to be localized within the query.
I tried wrapping the above expressions in django.db.models.functions.Cast()
, with output_field=DateTimeField()
, but it casts to UTC and not the local timezone.
Essentially what I need is the equivalent of the Postgres at time zone
feature to convert a naive time to localtime. Is there a way to do that in Django?
Yes. You can use any Postgres function by writing a custom django database function.
Here is a custom django database function for the equivalent of the Postgres at time zone
.
from django.db.models import ExpressionWrapper, F, Func
from django.db import models
class AtTimeZone(Func):
function = 'AT TIME ZONE'
template = "%(expressions)s %(function)s '%(timezone)s'"
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()
),
start_local_datetime=AtTimeZone(F('start_datetime', timezone='Europe/Berlin')
)
The above is for a model with the initial fields of: date
, start_time
, and end_time
.
Here are the docs regarding django's custom database functions. https://docs.djangoproject.com/en/4.0/ref/models/expressions/#func-expressions. As of the start of 2022, the docs don't provide many examples on how to create custom database functions. This should help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With