From 0c74c98facc2857d364d2bfbe32efa6ab74d3003 Mon Sep 17 00:00:00 2001 From: Jamie Cockburn Date: Tue, 24 Oct 2017 13:55:48 +0100 Subject: [PATCH] Stop JSONBoundField mangling invalid JSON (#5526) --- rest_framework/utils/serializer_helpers.py | 11 +++++++---- tests/test_bound_fields.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index fa79b6526..6b662a66c 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -86,10 +86,13 @@ class BoundField(object): class JSONBoundField(BoundField): def as_form_field(self): value = self.value - try: - value = json.dumps(self.value, sort_keys=True, indent=4) - except (TypeError, ValueError): - pass + # When HTML form input is used and the input is not valid + # value will be a JSONString, rather than a JSON primitive. + if not getattr(value, 'is_json_string', False): + try: + value = json.dumps(self.value, sort_keys=True, indent=4) + except (TypeError, ValueError): + pass return self.__class__(self._field, value, self.errors, self._prefix) diff --git a/tests/test_bound_fields.py b/tests/test_bound_fields.py index ade739d41..e90e65edf 100644 --- a/tests/test_bound_fields.py +++ b/tests/test_bound_fields.py @@ -1,3 +1,5 @@ +from django.http import QueryDict + from rest_framework import serializers @@ -160,3 +162,15 @@ class TestNestedBoundField: ) rendered_packed = ''.join(rendered.split()) assert rendered_packed == expected_packed + + +class TestJSONBoundField: + def test_as_form_fields(self): + class TestSerializer(serializers.Serializer): + json_field = serializers.JSONField() + + data = QueryDict(mutable=True) + data.update({'json_field': '{"some": ["json"}'}) + serializer = TestSerializer(data=data) + assert serializer.is_valid() is False + assert serializer['json_field'].as_form_field().value == '{"some": ["json"}'