Home > Software engineering >  Remove Z from DateTimeField in serializer
Remove Z from DateTimeField in serializer

Time:03-25

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()

CodePudding user response:

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

CodePudding user response:

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"]
  • Related