mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-02 19:40:13 +03:00
Fix JSONField.
This commit is contained in:
parent
f404fda29c
commit
42049daf75
|
@ -1756,6 +1756,12 @@ class HStoreField(DictField):
|
||||||
|
|
||||||
|
|
||||||
class JSONField(Field):
|
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 = {
|
default_error_messages = {
|
||||||
'invalid': _('Value must be valid JSON.')
|
'invalid': _('Value must be valid JSON.')
|
||||||
}
|
}
|
||||||
|
@ -1765,20 +1771,21 @@ class JSONField(Field):
|
||||||
super(JSONField, self).__init__(*args, **kwargs)
|
super(JSONField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def get_value(self, dictionary):
|
def get_value(self, dictionary):
|
||||||
if html.is_html_input(dictionary) and self.field_name in dictionary:
|
value = dictionary.get(self.field_name, empty)
|
||||||
# When HTML form input is used, mark up the input
|
if isinstance(value, six.binary_type):
|
||||||
# as being a JSON string, rather than a JSON primitive.
|
value = value.decode('utf-8')
|
||||||
class JSONString(six.text_type):
|
if isinstance(value, six.text_type):
|
||||||
def __new__(self, value):
|
return self.JSONString(value)
|
||||||
ret = six.text_type.__new__(self, value)
|
return 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):
|
def to_internal_value(self, data):
|
||||||
try:
|
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):
|
if isinstance(data, six.binary_type):
|
||||||
data = data.decode('utf-8')
|
data = data.decode('utf-8')
|
||||||
return json.loads(data)
|
return json.loads(data)
|
||||||
|
|
|
@ -2080,11 +2080,15 @@ class TestJSONField(FieldValues):
|
||||||
'a': 1,
|
'a': 1,
|
||||||
'b': ['some', 'list', True, 1.23],
|
'b': ['some', 'list', True, 1.23],
|
||||||
'3': None
|
'3': None
|
||||||
}),
|
}), (
|
||||||
|
'{"a":1}',
|
||||||
|
{'a': 1}
|
||||||
|
)
|
||||||
]
|
]
|
||||||
invalid_inputs = [
|
invalid_inputs = [
|
||||||
({'a': set()}, ['Value must be valid JSON.']),
|
({'a': set()}, ['Value must be valid JSON.']),
|
||||||
({'a': float('inf')}, ['Value must be valid JSON.']),
|
({'a': float('inf')}, ['Value must be valid JSON.']),
|
||||||
|
('invalid json', ['Value must be valid JSON.']),
|
||||||
]
|
]
|
||||||
outputs = [
|
outputs = [
|
||||||
({
|
({
|
||||||
|
@ -2099,19 +2103,6 @@ class TestJSONField(FieldValues):
|
||||||
]
|
]
|
||||||
field = serializers.JSONField()
|
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):
|
class TestBinaryJSONField(FieldValues):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user