Abhishek AN
Abhishek AN

Reputation: 808

Remove Z from DateTimeField in serializer

Is there a way to make my serializer print the datetimefield by default like this

 2022-03-28T00:00:00+00:00

Instead of this

 2022-03-23T03:16:00Z 

I get the first output when I do this

return obj.time.isoformat()

Upvotes: 0

Views: 1780

Answers (2)

annonymous
annonymous

Reputation: 816

Cause

If you look into the code of django-rest-framework in serializers.DateTimeField if datetime is UTC timezone, the UTC offset (+00:00) will get converted to Z as can be seen here

Solution

If you want to make it reusable for DateTimeField, you need to create a custom serializer DateTimeField that inherits from serializers.DateTimeField and override the to_representation method by coping codes from django-rest-framework and removing lines that convert UTC offset string to Z.

from restframework import ISO_8601
from restframework import serializers


class CustomDateTimeField(serializers.DateTimeField):

    def to_representation(self, value):
        if not value:
            return None

        output_format = getattr(self, 'format', api_settings.DATETIME_FORMAT)

        if output_format is None or isinstance(value, str):
            return value

        value = self.enforce_timezone(value)

        if output_format.lower() == ISO_8601:
            value = value.isoformat()
            # remove lines that convert "+00:00" to "Z"
            # See https://github.com/encode/django-rest-framework/blob/f4cf0260bf3c9323e798325702be690ca25949ca/rest_framework/fields.py#L1239:L1240
            return value
        return value.strftime(output_format)

Then use this in your serializer instead of serializers.DateTimeField

class MySerializer(serializers.Serializer):
    datetime = CustomDateTimeField()

Extra

If you want to use it in serializers.ModelSerializer, you need to follow below steps

  1. Create a custom ModelSerializer that inherits from serializers.ModelSerializer and set serializer_field_mapping attribute as follows
class CustomModelSerializer(serializers.ModelSerializer):
    serializer_field_mapping = {
        # copy serializer_field_mapping
        **serializers.ModelSerializer.serializer_field_mapping,
        # override models.DateTimeField to map to CustomDateTimeField
        models.DateTimeField: CustomDateTimeField,
    }
  1. Use CustomModelSerializer instead of serializers.ModelSerializer. E.g.
class LogSerializer(CustomModelSerializer):
    class Meta:
        model = Log
        fields = ["id", "created_at"]

Upvotes: 2

ThomasGth
ThomasGth

Reputation: 870

The simplest way to do it is to specify the format you want in your serializer:

class MySerializer(serializer.Serializer):

    my_date = serializers.DateTimeField(format='%Y-%m-%dT%H:%M')  # Specify your format here

Upvotes: 1

Related Questions