Skip to content

Commit 91fa8b9

Browse files
daggazcarltongibson
authored andcommitted
Stop JSONBoundField mangling invalid JSON (#5526) (#5527)
1 parent 1c9ad52 commit 91fa8b9

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

rest_framework/utils/serializer_helpers.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,13 @@ def as_form_field(self):
8686
class JSONBoundField(BoundField):
8787
def as_form_field(self):
8888
value = self.value
89-
try:
90-
value = json.dumps(self.value, sort_keys=True, indent=4)
91-
except (TypeError, ValueError):
92-
pass
89+
# When HTML form input is used and the input is not valid
90+
# value will be a JSONString, rather than a JSON primitive.
91+
if not getattr(value, 'is_json_string', False):
92+
try:
93+
value = json.dumps(self.value, sort_keys=True, indent=4)
94+
except (TypeError, ValueError):
95+
pass
9396
return self.__class__(self._field, value, self.errors, self._prefix)
9497

9598

tests/test_bound_fields.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from django.http import QueryDict
2+
13
from rest_framework import serializers
24

35

@@ -160,3 +162,15 @@ class ExampleSerializer(serializers.Serializer):
160162
)
161163
rendered_packed = ''.join(rendered.split())
162164
assert rendered_packed == expected_packed
165+
166+
167+
class TestJSONBoundField:
168+
def test_as_form_fields(self):
169+
class TestSerializer(serializers.Serializer):
170+
json_field = serializers.JSONField()
171+
172+
data = QueryDict(mutable=True)
173+
data.update({'json_field': '{"some": ["json"}'})
174+
serializer = TestSerializer(data=data)
175+
assert serializer.is_valid() is False
176+
assert serializer['json_field'].as_form_field().value == '{"some": ["json"}'

0 commit comments

Comments
 (0)