Commit 59b57e67 authored by Simon Charette's avatar Simon Charette
Browse files

Fixed #25867 -- Fixed a system check crash with nested ArrayFields.

Thanks to Jean Gourds for the report, Tim and Claude for the review.
parent 9c835990
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -29,9 +29,17 @@ class ArrayField(Field):
            self.default_validators.append(ArrayMaxLengthValidator(self.size))
        super(ArrayField, self).__init__(**kwargs)

    def contribute_to_class(self, cls, name, **kwargs):
        super(ArrayField, self).contribute_to_class(cls, name, **kwargs)
        self.base_field.model = cls
    @property
    def model(self):
        try:
            return self.__dict__['model']
        except KeyError:
            raise AttributeError("'%s' object has no attribute 'model'" % self.__class__.__name__)

    @model.setter
    def model(self, model):
        self.__dict__['model'] = model
        self.base_field.model = model

    def check(self, **kwargs):
        errors = super(ArrayField, self).check(**kwargs)
+2 −0
Original line number Diff line number Diff line
@@ -14,3 +14,5 @@ Bugfixes

* Fixed a regression in ``FormMixin`` causing forms to be validated twice
  (:ticket:`25548`).

* Fixed a system check crash with nested ``ArrayField``\s (:ticket:`25867`).
+21 −0
Original line number Diff line number Diff line
@@ -347,7 +347,9 @@ class TestChecks(PostgreSQLTestCase):
        model = MyModel()
        errors = model.check()
        self.assertEqual(len(errors), 1)
        # The inner CharField is missing a max_length.
        self.assertEqual(errors[0].id, 'postgres.E001')
        self.assertIn('max_length', errors[0].msg)

    def test_invalid_base_fields(self):
        test_apps = Apps(['postgres_tests'])
@@ -363,6 +365,25 @@ class TestChecks(PostgreSQLTestCase):
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0].id, 'postgres.E002')

    def test_nested_field_checks(self):
        """
        Nested ArrayFields are permitted.
        """
        test_apps = Apps(['postgres_tests'])

        class MyModel(PostgreSQLModel):
            field = ArrayField(ArrayField(models.CharField()))

            class Meta:
                apps = test_apps

        model = MyModel()
        errors = model.check()
        self.assertEqual(len(errors), 1)
        # The inner CharField is missing a max_length.
        self.assertEqual(errors[0].id, 'postgres.E001')
        self.assertIn('max_length', errors[0].msg)


@unittest.skipUnless(connection.vendor == 'postgresql', "PostgreSQL specific tests")
class TestMigrations(TransactionTestCase):