[Django]-Django-rest-framework timezone aware renderers/parsers

36👍

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',
        )
👤yakxxx

17👍

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')
👤Ramast

4👍

Since Django REST Framework v3.8.0(released in May, 2018), you don’t need a custom DateTimeField any more.

In previous versions, Django REST Framework only convert native datetime to timezone aware datetime when parsing the date(DateTimeField.to_internal_value()), but do not convert when rendering the datatime field(DateTimeField.to_representation()). This is fixed in DRF v3.8.0.

You may need to change the following settings:

  1. USE_TZ must be True
  2. set TIME_ZONE to specify a default timezone
  3. set REST_FRAMEWORK.DATETIME_FORMAT to the format that fits your frontend code.

Leave a comment