vinay kumar
vinay kumar

Reputation: 593

Django Rest Framework Json data monkey patching

I'm Facing a problem with float number like 3.333333333 and I want to make it 3.33. I don't want to change all Serializer class from where this type of value is coming. There are thousand serializers and they have multiple fields which have values like 3.333333333.

Could you please help me to find monkey patching type solution so that I'll write one class or function to convert only float values.

Upvotes: 9

Views: 985

Answers (1)

vinay kumar
vinay kumar

Reputation: 593

I did some code its working. I made changes in following files

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

Upvotes: 1

Related Questions