summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkash Kumar Sen <Akash-Kumar-Sen@users.noreply.github.com>2023-06-15 23:13:49 +0530
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-06-20 08:10:53 +0200
commit82a588a6bce37e1fe0a1d266282034136460b37a (patch)
tree4a94be2f027158a5e3887bb5d87c7e8508e0cecb
parentd6e9ec40145b9edc65e8d0c65bd3f4ef8a7a27bb (diff)
Fixed #34634 -- Adjusted system check for clashing fields to warn about links to common parent for MTI models.
-rw-r--r--django/db/models/base.py15
-rw-r--r--tests/invalid_models_tests/test_models.py25
2 files changed, 40 insertions, 0 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 959b72c93b..0c4a5ddcfc 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -1775,6 +1775,21 @@ class Model(AltersData, metaclass=ModelBase):
if f not in used_fields:
used_fields[f.name] = f
+ # Check that parent links in diamond-shaped MTI models don't clash.
+ for parent_link in cls._meta.parents.values():
+ if not parent_link:
+ continue
+ clash = used_fields.get(parent_link.name) or None
+ if clash:
+ errors.append(
+ checks.Error(
+ f"The field '{parent_link.name}' clashes with the field "
+ f"'{clash.name}' from model '{clash.model._meta}'.",
+ obj=cls,
+ id="models.E006",
+ )
+ )
+
for f in cls._meta.local_fields:
clash = used_fields.get(f.name) or used_fields.get(f.attname) or None
# Note that we may detect clash between user-defined non-unique
diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py
index ffc7579e10..9e2a37b79a 100644
--- a/tests/invalid_models_tests/test_models.py
+++ b/tests/invalid_models_tests/test_models.py
@@ -1070,6 +1070,31 @@ class ShadowingFieldsTests(SimpleTestCase):
],
)
+ def test_diamond_mti_common_parent(self):
+ class GrandParent(models.Model):
+ pass
+
+ class Parent(GrandParent):
+ pass
+
+ class Child(Parent):
+ pass
+
+ class MTICommonParentModel(Child, GrandParent):
+ pass
+
+ self.assertEqual(
+ MTICommonParentModel.check(),
+ [
+ Error(
+ "The field 'grandparent_ptr' clashes with the field "
+ "'grandparent_ptr' from model 'invalid_models_tests.parent'.",
+ obj=MTICommonParentModel,
+ id="models.E006",
+ )
+ ],
+ )
+
def test_id_clash(self):
class Target(models.Model):
pass