Refs #27003 -- Fixed JSONField crash on converted values.

This commit is contained in:
Brandon Chinn 2016-11-11 17:07:31 -08:00 committed by Tim Graham
parent 6573274161
commit eed6150009
2 changed files with 21 additions and 1 deletions

View File

@ -11,6 +11,10 @@ class InvalidJSONInput(six.text_type):
pass pass
class JSONString(six.text_type):
pass
class JSONField(forms.CharField): class JSONField(forms.CharField):
default_error_messages = { default_error_messages = {
'invalid': _("'%(value)s' value must be valid JSON."), 'invalid': _("'%(value)s' value must be valid JSON."),
@ -22,14 +26,20 @@ class JSONField(forms.CharField):
return value return value
if value in self.empty_values: if value in self.empty_values:
return None return None
elif isinstance(value, (list, dict, int, float, JSONString)):
return value
try: try:
return json.loads(value) converted = json.loads(value)
except ValueError: except ValueError:
raise forms.ValidationError( raise forms.ValidationError(
self.error_messages['invalid'], self.error_messages['invalid'],
code='invalid', code='invalid',
params={'value': value}, params={'value': value},
) )
if isinstance(converted, six.text_type):
return JSONString(converted)
else:
return converted
def bound_data(self, data, initial): def bound_data(self, data, initial):
if self.disabled: if self.disabled:

View File

@ -365,3 +365,13 @@ class TestFormField(PostgreSQLTestCase):
field = CustomJSONField() field = CustomJSONField()
self.assertIsInstance(field.widget, widgets.Input) self.assertIsInstance(field.widget, widgets.Input)
def test_already_converted_value(self):
field = forms.JSONField(required=False)
tests = [
'["a", "b", "c"]', '{"a": 1, "b": 2}', '1', '1.5', '"foo"',
'true', 'false', 'null',
]
for json_string in tests:
val = field.clean(json_string)
self.assertEqual(field.clean(val), val)