Удаление Z из поля DateTimeField в сериализаторе

Есть ли способ заставить мой сериализатор выводить поле datetime по умолчанию следующим образом

2022-03-28T00:00:00+00:00 Вместо этого

2022-03-23T03:16:00Z Я получаю первый вывод, когда я делаю это

return obj.time.isoformat()

Самый простой способ сделать это - указать нужный формат в вашем сериализаторе:

class MySerializer(serializer.Serializer):

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

Причина

Если посмотреть на код django-rest-framework в serializers.DateTimeField если datetime - это часовой пояс UTC, то смещение UTC (+00:00) будет преобразовано в Z, как можно увидеть здесь

Решение

Если вы хотите сделать его многоразовым для DateTimeField, вам нужно создать пользовательский сериализатор DateTimeField, который наследуется от serializers.DateTimeField и переопределить метод to_representation, скопировав коды из django-rest-framework и удалив строки, которые преобразуют строку смещения UTC в 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)

Тогда используйте это в вашем сериализаторе вместо serializers.DateTimeField

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

Extra

Если вы хотите использовать его в serializers.ModelSerializer, вам нужно выполнить следующие шаги

  1. Создайте пользовательский ModelSerializer, который наследуется от serializers.ModelSerializer и установите serializer_field_mapping атрибут следующим образом
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. Используйте CustomModelSerializer вместо serializers.ModelSerializer. Например,
class LogSerializer(CustomModelSerializer):
    class Meta:
        model = Log
        fields = ["id", "created_at"]
Вернуться на верх