diff options
| author | Brandon Chinn <brandonchinn178@gmail.com> | 2016-11-11 17:07:31 -0800 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-11-15 18:43:55 -0500 |
| commit | eed615000903ec7b659c3563b7b4b4b3f34f5636 (patch) | |
| tree | 388341ebb4eca26fe435d464a6b27ee61b5d5574 | |
| parent | 6573274161ee589e89077192239e0bd01cbd692a (diff) | |
Refs #27003 -- Fixed JSONField crash on converted values.
| -rw-r--r-- | django/contrib/postgres/forms/jsonb.py | 12 | ||||
| -rw-r--r-- | tests/postgres_tests/test_json.py | 10 |
2 files changed, 21 insertions, 1 deletions
diff --git a/django/contrib/postgres/forms/jsonb.py b/django/contrib/postgres/forms/jsonb.py index 83a62a8b7c..719de3ae66 100644 --- a/django/contrib/postgres/forms/jsonb.py +++ b/django/contrib/postgres/forms/jsonb.py @@ -11,6 +11,10 @@ class InvalidJSONInput(six.text_type): pass +class JSONString(six.text_type): + pass + + class JSONField(forms.CharField): default_error_messages = { 'invalid': _("'%(value)s' value must be valid JSON."), @@ -22,14 +26,20 @@ class JSONField(forms.CharField): return value if value in self.empty_values: return None + elif isinstance(value, (list, dict, int, float, JSONString)): + return value try: - return json.loads(value) + converted = json.loads(value) except ValueError: raise forms.ValidationError( self.error_messages['invalid'], code='invalid', params={'value': value}, ) + if isinstance(converted, six.text_type): + return JSONString(converted) + else: + return converted def bound_data(self, data, initial): if self.disabled: diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py index 78dded31a9..9691329a49 100644 --- a/tests/postgres_tests/test_json.py +++ b/tests/postgres_tests/test_json.py @@ -365,3 +365,13 @@ class TestFormField(PostgreSQLTestCase): field = CustomJSONField() 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) |
