diff --git a/django/db/models/base.py b/django/db/models/base.py index 7bc726a617..f95c182566 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1308,7 +1308,7 @@ class Model(six.with_metaclass(ModelBase)): used_fields = {} # name or attname -> field # Check that multi-inheritance doesn't cause field name shadowing. - for parent in cls._meta.parents: + for parent in cls._meta.get_parent_list(): for f in parent._meta.local_fields: clash = used_fields.get(f.name) or used_fields.get(f.attname) or None if clash: diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index 3c874ad11b..f67223963b 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -483,6 +483,31 @@ class ShadowingFieldsTests(IsolatedModelsTestCase): ] self.assertEqual(errors, expected) + def test_multigeneration_inheritance(self): + class GrandParent(models.Model): + clash = models.IntegerField() + + class Parent(GrandParent): + pass + + class Child(Parent): + pass + + class GrandChild(Child): + clash = models.IntegerField() + + errors = GrandChild.check() + expected = [ + Error( + "The field 'clash' clashes with the field 'clash' " + "from model 'invalid_models_tests.grandparent'.", + hint=None, + obj=GrandChild._meta.get_field('clash'), + id='models.E006', + ) + ] + self.assertEqual(errors, expected) + def test_id_clash(self): class Target(models.Model): pass