diff options
| author | Adam Johnson <me@adamj.eu> | 2024-03-17 08:43:04 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-17 09:43:04 +0100 |
| commit | 7646b9023da7e1f6f3a871959db027b3ea36eebb (patch) | |
| tree | b0c15ba4935d43aae75a8d1236bd698f37556f0e | |
| parent | b07e2d57a000d98c73492e5242fed91d502a780a (diff) | |
Fixed #35301 -- Fixed Options._property_names for overriden properties.
Regression in faeb92ea13f0c1b2cc83f45b512f2c41cfb4f02d.
| -rw-r--r-- | django/db/models/options.py | 4 | ||||
| -rw-r--r-- | tests/invalid_models_tests/test_models.py | 11 |
2 files changed, 14 insertions, 1 deletions
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) |
