summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAron Podrigal <aronp@guaranteedplus.com>2015-01-30 04:40:25 -0500
committerTim Graham <timograham@gmail.com>2015-02-09 08:43:40 -0500
commiteb9fbc0b1d6497f20204d9032852a5b4ae8b2466 (patch)
tree8ddde42e0143940f75f7bc035a4a9b14d673e7f9
parent8cb2cfdda5a9a913dc761eba48b56b7d2f4ce2e7 (diff)
[1.8.x] Fixed #24249 -- Improved field shadowing validation in model multi-inheritance.
Backport of 4d73303ee974c5f1ea6af984d4578d817825026d from master
-rw-r--r--django/db/models/base.py2
-rw-r--r--tests/invalid_models_tests/test_models.py25
2 files changed, 26 insertions, 1 deletions
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