Django-rest-framework: Две немного разные сериализации даты и времени iso 8601

Созданный на 11 июл. 2016  ·  3Комментарии  ·  Источник: encode/django-rest-framework

Контрольный список

  • [x] Я убедился, что эта проблема существует в ветви master платформы Django REST.
  • [x] Я искал похожие проблемы как в открытых, так и в закрытых тикетах и ​​не могу найти дубликатов.
  • [x] Это не вопрос использования. (Вместо этого их следует направлять в дискуссионную группу .)
  • [x] Это не может рассматриваться как сторонняя библиотека. (Мы предпочитаем, чтобы новые функции были в форме сторонних библиотек, где это возможно.)
  • [x] Я свел проблему к простейшему случаю.
  • [] Я включил неудачный тест в качестве запроса на вытягивание. (Если вы не можете этого сделать, мы все равно можем принять проблему.)

    Действия по воспроизведению

Реализация сериализации datetime в формате ISO-8601 несовместима с кодовой базой.
В https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/fields.py#L1094 микросекунды включены в сериализованное значение
В https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/utils/encoders.py#L30 только миллисекунды

Ожидаемое поведение

Я ожидал последовательной реализации.

Фактическое поведение

N / A

Самый полезный комментарий

@georgejlee Я использую специальный рендерер, чтобы обойти это:

import datetime

from rest_framework.renderers import JSONRenderer
from rest_framework.utils.encoders import JSONEncoder

class MilliSecondEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            representation = obj.isoformat()
            if obj.microsecond:
                representation = representation[:23] + representation[26:]
            if representation.endswith('+00:00'):
                representation = representation[:-6] + 'Z'
            return representation
        else:
            return super().default(obj)


class JSONRenderer(JSONRenderer):
    encoder_class = MilliSecondEncoder

Хм, изменение DEFAULT_RENDERER_CLASSES на пользовательский рендерер не повлияло на рендеринг моих наборов просмотра. Пришлось явно установить renderer_class, странно.

Все 3 Комментарий

В настоящее время некоторые клиенты моего API требуют даты с точностью до миллисекунды и не могут обрабатывать микросекунды. Я добился этого, установив для параметра DATETIME_FORMAT значение None в настройках DRF 3.3. Обновление до 3.4 ломает это поведение. Есть ли простой способ вернуть прежнее поведение? Я не могу понять, как указать строку формата даты и времени, которая дает мне формат ECMA-262. Спасибо.

@georgejlee Я использую специальный рендерер, чтобы обойти это:

import datetime

from rest_framework.renderers import JSONRenderer
from rest_framework.utils.encoders import JSONEncoder

class MilliSecondEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            representation = obj.isoformat()
            if obj.microsecond:
                representation = representation[:23] + representation[26:]
            if representation.endswith('+00:00'):
                representation = representation[:-6] + 'Z'
            return representation
        else:
            return super().default(obj)


class JSONRenderer(JSONRenderer):
    encoder_class = MilliSecondEncoder

Хм, изменение DEFAULT_RENDERER_CLASSES на пользовательский рендерер не повлияло на рендеринг моих наборов просмотра. Пришлось явно установить renderer_class, странно.

Если кто-то еще наткнется на это, пытаясь настроить DRF для использования пользовательского кодировщика через encoder_class для datetime . Проблема, из-за которой решение в https://github.com/encode/django-rest-framework/issues/4255#issuecomment -234560555 не работало на меня, заключалась в том, что DRF будет использовать свой встроенный кодировщик, если только в поле не указано DateTimeField имеет свой format kwarg, установленный в None ИЛИ, если вы не укажете сериализаторы DateTimeField , тогда вам нужно установить конфигурацию REST_FRAMEWORK за DEFAULT_FORMAT: None в вашем settings.py . Только тогда будет использоваться custom encoder .

Причина в том, что поле (я) сериализатора (или средство визуализации полей по умолчанию) будет использоваться для форматирования Response до того, как пользовательский Renderer будет использован для визуализации datetime . Таким образом, поле datetime уже будет строкой, а JSONEncoder по умолчанию не будет вызывать пользовательский кодировщик, поскольку типы Python по умолчанию обрабатываются кодировщиком, поэтому метод пользовательского кодировщика default не будет вызываться.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги