mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-02 11:30:12 +03:00
Fix JSONField.
This commit is contained in:
parent
f404fda29c
commit
42049daf75
|
@ -1756,6 +1756,12 @@ class HStoreField(DictField):
|
|||
|
||||
|
||||
class JSONField(Field):
|
||||
class JSONString(six.text_type):
|
||||
def __new__(self, value):
|
||||
ret = six.text_type.__new__(self, value)
|
||||
ret.is_json_string = True
|
||||
return ret
|
||||
|
||||
default_error_messages = {
|
||||
'invalid': _('Value must be valid JSON.')
|
||||
}
|
||||
|
@ -1765,20 +1771,21 @@ class JSONField(Field):
|
|||
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 primitive.
|
||||
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)
|
||||
value = dictionary.get(self.field_name, empty)
|
||||
if isinstance(value, six.binary_type):
|
||||
value = value.decode('utf-8')
|
||||
if isinstance(value, six.text_type):
|
||||
return self.JSONString(value)
|
||||
return value
|
||||
|
||||
def to_internal_value(self, data):
|
||||
try:
|
||||
if self.binary or getattr(data, 'is_json_string', False):
|
||||
serialized_json_types = (
|
||||
six.text_type,
|
||||
six.binary_type,
|
||||
self.JSONString
|
||||
)
|
||||
if self.binary or isinstance(data, serialized_json_types):
|
||||
if isinstance(data, six.binary_type):
|
||||
data = data.decode('utf-8')
|
||||
return json.loads(data)
|
||||
|
|
|
@ -2080,11 +2080,15 @@ class TestJSONField(FieldValues):
|
|||
'a': 1,
|
||||
'b': ['some', 'list', True, 1.23],
|
||||
'3': None
|
||||
}),
|
||||
}), (
|
||||
'{"a":1}',
|
||||
{'a': 1}
|
||||
)
|
||||
]
|
||||
invalid_inputs = [
|
||||
({'a': set()}, ['Value must be valid JSON.']),
|
||||
({'a': float('inf')}, ['Value must be valid JSON.']),
|
||||
('invalid json', ['Value must be valid JSON.']),
|
||||
]
|
||||
outputs = [
|
||||
({
|
||||
|
@ -2099,19 +2103,6 @@ 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