Django-rest-framework: 两个稍有不同的iso 8601日期时间序列化

创建于 2016-07-11  ·  3评论  ·  资料来源: encode/django-rest-framework

检查清单

  • [x]我已验证针对Django REST框架的master分支存在该问题。
  • [x]我已经在开放票和封闭票中搜索了类似的问题,但找不到重复的票。
  • [x]这不是用法问题。 (这些人应该直接转到讨论组。)
  • [x]这不能作为第三方库处理。 (我们希望新功能尽可能采用第三方库的形式。)
  • [x]我已将问题简化为最简单的情况。
  • []我已将测试失败作为拉入请求。 (如果您无法执行此操作,我们仍然可以接受该问题。)

    重现步骤

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中,只有毫秒是

预期行为

我希望实施的一致性。

实际行为

不适用

最有用的评论

@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的某些客户端要求使用毫秒精度的日期,并且无法处理微秒。 我是通过在DRF 3.3的设置中将“ DATETIME_FORMAT”设置为“无”来实现的。 升级到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将使用其内置编码器,除非该字段的DateTimeFieldformat kwarg设置为None或,如果您未指定DateTimeField序列化程序,则需要设置REST_FRAMEWORK的配置为DEFAULT_FORMAT: Nonesettings.py 。 只有这样才能使用custom encoder

原因是,在使用自定义Renderer渲染datetime之前,将使用序列化程序字段(或默认字段渲染器)格式化Response datetime 。 因此datetime字段已经是一个字符串,默认的JSONEncoder不会调用自定义编码器,因为默认的Python类型是由该编码器处理的,因此不会调用自定义编码器的default方法。

此页面是否有帮助?
0 / 5 - 0 等级