Django Rest Framework Json 数据猴子补丁

Posted

技术标签:

【中文标题】Django Rest Framework Json 数据猴子补丁【英文标题】:Django Rest Framework Json data monkey patching 【发布时间】:2016-06-26 15:41:14 【问题描述】:

我遇到了像 3.333333333 这样的浮点数问题,我想将其设为 3.33。我不想更改所有 Serializer 类的此类值的来源。有上千个序列化器,它们有多个字段,其值类似于 3.333333333

能否请您帮我找到猴子修补类型的解决方案,以便我编写一个类或函数来仅转换浮点值。

【问题讨论】:

返回 3.333333 有什么问题?您的 api 的任何使用者都可以将其显示为 3.33。让客户端处理格式。 android中,需要指定float、int或long等数据类型。假设最初的数据是 4.56,但现在是 3.3333333。所以现在很难将所有浮点数据类型更改为长。这就是为什么我需要后端而不是客户端的解决方案。 我想 vinay 是对的,我也遇到了同样的问题。从客户端转换它们(尤其是android不是一个好主意)@vinaykumar,如果您还写下您的尝试(您尝试过什么),人们会很乐意回答您的问题。我想您需要对从 JSONEncode 类调用的 json.dumps 进行monkeypatch。 序列化器字段是否都属于同一类型?例如FloatField? @ilse2005 所有字段都不是FloatField。我正在使用 DRF 和 mongoengine。 class MyModel(me.Document): accuracy = me.DictField(default=)我也在使用这样的字段。 【参考方案1】:

我做了一些代码它的工作。 我对以下文件进行了更改

settings.py

REST_FRAMEWORK = 
 'DEFAULT_RENDERER_CLASSES': (

    'utils.renderers.PalJSONRenderer',

    'rest_framework.renderers.BrowsableAPIRenderer',
 )

utils/renderers.py

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

        from json.encoder import encode_basestring_ascii, encode_basestring, INFINITY, _make_iterencode


        class CustomJSONEncoder(JSONEncoder):

            def iterencode(self, o, _one_shot=False):
                """Encode the given object and yield each string
                representation as available.

                For example::

                    for chunk in JSONEncoder().iterencode(bigobject):
                        mysocket.write(chunk)

                """
                # Hack to enforce
                c_make_encoder = None
                if self.check_circular:
                    markers = 
                else:
                    markers = None
                if self.ensure_ascii:
                    _encoder = encode_basestring_ascii
                else:
                    _encoder = encode_basestring

                def floatstr(o, allow_nan=self.allow_nan, _repr=lambda o: format(o, '.2f'), _inf=INFINITY, _neginf=-INFINITY):
                    # Check for specials.  Note that this type of test is processor
                    # and/or platform-specific, so do tests which don't depend on the
                    # internals.

                    if o != o:
                        text = 'NaN'
                    elif o == _inf:
                        text = 'Infinity'
                    elif o == _neginf:
                        text = '-Infinity'
                    else:
                        return _repr(o)

                    if not allow_nan:
                        raise ValueError(
                            "Out of range float values are not JSON compliant: " +
                            repr(o))

                    return text

                if (_one_shot and c_make_encoder is not None and self.indent is None):
                    _iterencode = c_make_encoder(
                        markers, self.default, _encoder, self.indent,
                        self.key_separator, self.item_separator, self.sort_keys,
                        self.skipkeys, self.allow_nan)
                else:
                    _iterencode = _make_iterencode(
                        markers, self.default, _encoder, self.indent, floatstr,
                        self.key_separator, self.item_separator, self.sort_keys,
                        self.skipkeys, _one_shot)
                return _iterencode(o, 0)


        class PalJSONRenderer(JSONRenderer):
            encoder_class = CustomJSONEncoder

【讨论】:

以上是关于Django Rest Framework Json 数据猴子补丁的主要内容,如果未能解决你的问题,请参考以下文章

Django-rest-framework 和 django-rest-framework-jwt APIViews and validation Authorization headers

Django Rest Framework 和 django Rest Framework simplejwt 两因素身份验证

怎么安装django rest framework

django rest framework中文介绍

17-Django-Django REST framework-REST framework及RESTful简介

为啥 django-rest-framework 不显示 OneToOneField 数据 - django