mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-29 04:54:00 +03:00
When HTML form input is used with JSONField, treat the input as a JSON encoded string, not a JSON primative. (#4565)
This commit is contained in:
parent
b419970431
commit
26e51ecd6c
|
@ -1594,9 +1594,21 @@ class JSONField(Field):
|
|||
self.binary = kwargs.pop('binary', False)
|
||||
super(JSONField, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_value(self, dictionary):
|
||||
if html.is_html_input(dictionary) and self.field_name in dictionary:
|
||||
# When HTML form input is used, mark up the input
|
||||
# as being a JSON string, rather than a JSON primative.
|
||||
class JSONString(six.text_type):
|
||||
def __new__(self, value):
|
||||
ret = six.text_type.__new__(self, value)
|
||||
ret.is_json_string = True
|
||||
return ret
|
||||
return JSONString(dictionary[self.field_name])
|
||||
return dictionary.get(self.field_name, empty)
|
||||
|
||||
def to_internal_value(self, data):
|
||||
try:
|
||||
if self.binary:
|
||||
if self.binary or getattr(data, 'is_json_string', False):
|
||||
if isinstance(data, six.binary_type):
|
||||
data = data.decode('utf-8')
|
||||
return json.loads(data)
|
||||
|
|
|
@ -1756,6 +1756,19 @@ class TestJSONField(FieldValues):
|
|||
]
|
||||
field = serializers.JSONField()
|
||||
|
||||
def test_html_input_as_json_string(self):
|
||||
"""
|
||||
HTML inputs should be treated as a serialized JSON string.
|
||||
"""
|
||||
class TestSerializer(serializers.Serializer):
|
||||
config = serializers.JSONField()
|
||||
|
||||
data = QueryDict(mutable=True)
|
||||
data.update({'config': '{"a":1}'})
|
||||
serializer = TestSerializer(data=data)
|
||||
assert serializer.is_valid()
|
||||
assert serializer.validated_data == {'config': {"a": 1}}
|
||||
|
||||
|
||||
class TestBinaryJSONField(FieldValues):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue
Block a user