From 7646b9023da7e1f6f3a871959db027b3ea36eebb Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 17 Mar 2024 08:43:04 +0000 Subject: [PATCH] Fixed #35301 -- Fixed Options._property_names for overriden properties. Regression in faeb92ea13f0c1b2cc83f45b512f2c41cfb4f02d. --- django/db/models/options.py | 4 +++- tests/invalid_models_tests/test_models.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/django/db/models/options.py b/django/db/models/options.py index f842faf0da..ed7be7dd7a 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -969,12 +969,14 @@ class Options: def _property_names(self): """Return a set of the names of the properties defined on the model.""" names = set() + seen = set() for klass in self.model.__mro__: names |= { name for name, value in klass.__dict__.items() - if isinstance(value, property) + if isinstance(value, property) and name not in seen } + seen |= set(klass.__dict__) return frozenset(names) @cached_property diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index a589fec807..8b6d705acb 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -1343,6 +1343,17 @@ class OtherModelTests(SimpleTestCase): ], ) + def test_inherited_overriden_property_no_clash(self): + class Cheese: + @property + def filling_id(self): + pass + + class Sandwich(Cheese, models.Model): + filling = models.ForeignKey("self", models.CASCADE) + + self.assertEqual(Sandwich.check(), []) + def test_single_primary_key(self): class Model(models.Model): foo = models.IntegerField(primary_key=True)