Commit 5bce6659 authored by Claude Paroz's avatar Claude Paroz
Browse files

[1.8.x] Fixed #26215 -- Fixed RangeField/ArrayField serialization with None values

Also added tests for HStoreField.
Thanks Aleksey Bukin for the report and Tim Graham for the initial patch and
the review.
Backport of 928c12eb from master.
parent 766fbcb1
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -95,6 +95,9 @@ class ArrayField(Field):
        base_field = self.base_field

        for val in vals:
            if val is None:
                values.append(None)
            else:
                obj = AttributeSetter(base_field.attname, val)
                values.append(base_field.value_to_string(obj))
        return json.dumps(values)
+6 −2
Original line number Diff line number Diff line
@@ -51,7 +51,11 @@ class RangeField(models.Field):
        base_field = self.base_field
        result = {"bounds": value._bounds}
        for end in ('lower', 'upper'):
            obj = AttributeSetter(base_field.attname, getattr(value, end))
            val = getattr(value, end)
            if val is None:
                result[end] = None
            else:
                obj = AttributeSetter(base_field.attname, val)
                result[end] = base_field.value_to_string(obj)
        return json.dumps(result)

+4 −0
Original line number Diff line number Diff line
@@ -17,3 +17,7 @@ Bugfixes

* Made ``forms.FileField`` and ``utils.translation.lazy_number()`` picklable
  (:ticket:`26212`).

* Fixed :class:`~django.contrib.postgres.fields.RangeField` and
  :class:`~django.contrib.postgres.fields.ArrayField` serialization with
  ``None`` values (:ticket:`26215`).
+5 −3
Original line number Diff line number Diff line
@@ -412,16 +412,18 @@ class TestMigrations(TransactionTestCase):


class TestSerialization(TestCase):
    test_data = '[{"fields": {"field": "[\\"1\\", \\"2\\"]"}, "model": "postgres_tests.integerarraymodel", "pk": null}]'
    test_data = (
        '[{"fields": {"field": "[\\"1\\", \\"2\\", null]"}, "model": "postgres_tests.integerarraymodel", "pk": null}]'
    )

    def test_dumping(self):
        instance = IntegerArrayModel(field=[1, 2])
        instance = IntegerArrayModel(field=[1, 2, None])
        data = serializers.serialize('json', [instance])
        self.assertEqual(json.loads(data), json.loads(self.test_data))

    def test_loading(self):
        instance = list(serializers.deserialize('json', self.test_data))[0].object
        self.assertEqual(instance.field, [1, 2])
        self.assertEqual(instance.field, [1, 2, None])


class TestValidation(TestCase):
+8 −1
Original line number Diff line number Diff line
@@ -130,7 +130,8 @@ class TestQuerying(TestCase):


class TestSerialization(TestCase):
    test_data = '[{"fields": {"field": "{\\"a\\": \\"b\\"}"}, "model": "postgres_tests.hstoremodel", "pk": null}]'
    test_data = ('[{"fields": {"field": "{\\"a\\": \\"b\\"}"}, '
                 '"model": "postgres_tests.hstoremodel", "pk": null}]')

    def test_dumping(self):
        instance = HStoreModel(field={'a': 'b'})
@@ -141,6 +142,12 @@ class TestSerialization(TestCase):
        instance = list(serializers.deserialize('json', self.test_data))[0].object
        self.assertEqual(instance.field, {'a': 'b'})

    def test_roundtrip_with_null(self):
        instance = HStoreModel(field={'a': 'b', 'c': None})
        data = serializers.serialize('json', [instance])
        new_instance = list(serializers.deserialize('json', data))[0].object
        self.assertEqual(instance.field, new_instance.field)


class TestValidation(TestCase):

Loading