I'm building an app that would serve people located in different places arround the world.
I'm using Django-Rest-Framwork for the communication between the clients and the server.
All DateTime values are saved to the DB as UTC (I have USE_TZ = True and TIME_ZONE = 'Greenwich' in settings.py).
I will be getting from the user his/her local timezone.
To test DRF for timezone awareness I wrote this middleware with fixed timezone:
import pytz
from django.utils import timezone
class TimezoneMiddleware(object):
def process_request(self, request):
timezone.activate(pytz.timezone("Asia/Jerusalem"))
The problem is:
I have a case in which I'm getting from the user "start_time" and "end_time" fields containting datetimes in the user's LOCAL timezone which gets through the UnicodeJSONRenderer to a ModelSerializer and then saved to the DB. However, they are saved as if they were in UTC.
At this point I would expect the serializer (or parser) to treat the datetime input from the user as datetime that needs to be converted from "Asia/Jerusalem" to UTC before saving to the DB since I performed timezone.activate(pytz.timezone("Asia/Jerusalem")).
The same goes when the data is parsed back in the response through JSONParser.
While expecting DateTime fields in the returned JSON to be in the timezone activated in the middleware, they are returned as UTC.
How can I easily achieve that in DRF?
I had the same problem and solved it by adding new type of field:
class DateTimeTzAwareField(serializers.DateTimeField):
def to_native(self, value):
value = timezone.localtime(value)
return super(DateTimeTzAwareField, self).to_native(value)
and now you can use it in ModelSerializer:
class XSerializer(serializers.ModelSerializer):
start = DateTimeTzAwareField()
end = DateTimeTzAwareField()
class Meta:
model = XModel
fields = (
'id',
'start',
'end',
)
The answer by @yakxxx seems to be the best solution. I am posting it again after updating it to work with newer versions of restframework
inside my directory (common/serializers.py)
from rest_framework import serializers
from django.utils import timezone
class DateTimeFieldWihTZ(serializers.DateTimeField):
def to_representation(self, value):
value = timezone.localtime(value)
return super(DateTimeFieldWihTZ, self).to_representation(value)
Inside my application
from common.serializers import DateTimeFieldWihTZ
class MyObjectSerializer(serializers.ModelSerializer):
start = DateTimeFieldWihTZ(format='%d %b %Y %I:%M %p')
end = DateTimeFieldWihTZ(format='%d %b %Y %I:%M %p')
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