I'm trying to make a proper date handling setup for my web app. I have a model that looks something like this
class Entity(models.Model):
name = models.CharField(max_length=255)
date = models.DateTimeField()
User can send a request to my DRF endpoint /api/v1/entity/
to get a list of such entities. Now there is a requirement that user should be able to request all Entity
objects for a single day, which is determined by the date parameter. Dates are stored in UTC in the database while users of this app are not in a UTC timezone.
User can create an entity with the following date 2018-06-19T01:00:00+02:00
, which is stored as 2018-06-18T23:00:00Z
in the database. Now if I try to list all entities user has created for 2018-06-19
nothing's returned, but filtering by 2018-06-18
returns one entry.
This is the code setup I'm using:
http://127.0.0.1:8000/api/v1/entity/?date=2018-06-18
.
def get_queryset(self):
user = self.request.user
entities = Entity.objects.filter(owner=user)
date = self.request.query_params.get('date')
if date:
entities = entities.filter(date__date=date)
return entities
So in this case the appropriate date range would be 2018-06-18T23:00:00Z
- 2018-06-19T23:00:00Z
. What's the correct approach to fetch all entities for a single day (or a date range) in user's timezone?
Time zone support is disabled by default. To enable it, set USE_TZ = True in your settings file. In Django 5.0, time zone support will be enabled by default. Time zone support uses zoneinfo , which is part of the Python standard library from Python 3.9.
When USE_TZ is True, this is the default time zone that Django will use to display datetimes in templates and to interpret datetimes entered in forms.
WhIf I understood correctly, You have to convert the local DateTime
to equivalent UTC
time and query to the DB. So I defined a simple timeconversion function below
import pytz
from datetime import datetime
def convert_to_UTC(local_tz,dt_1,dt_2):
"""
local_tz : any possible timezone which supports pytz lib (https://stackoverflow.com/questions/13866926/is-there-a-list-of-pytz-timezones)
dt_1 and dt_2 : local datetime in string in this format ->> '%Y-%m-%dT%H:%M:%S'
return a list as ->> [utc_equivalent_of_dt_1_in_string,utc_equivalent_of_dt_2_in_string]
"""
format='%Y-%m-%dT%H:%M:%S'
pytz_local_tz = pytz.timezone(local_time_zone)
dt_obj_from_date_time = datetime.strptime(dt_1,format)
dt_obj_to_date_time = datetime.strptime(dt_2,format)
return [pytz_local_tz.localize(dt_obj_from_date_time).astimezone(tz=pytz.utc).strftime(format),
pytz_local_tz.localize(dt_obj_to_date_time).astimezone(tz=pytz.utc).strftime(format)]
To utilize this fuction, change your get_queryset()
method as below,
def get_queryset(self):
user = self.request.user
entities = Entity.objects.filter(owner=user)
date_from = self.request.query_params.get('date_from')
date_to = self.request.query_params.get('date_to')
if date_from and date_to:
entities = entities.filter(date__range=convert_to_UTC('Asia/Kolkata', date_from, date_to))
return entities
hence the url will be like, /api/v1/entity/?date_from=2018-06-18T23:00:00&date_to=2018-06-19T23:00:00
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