diff options
| author | Ahmed Nassar <a.moh.nassar00@gmail.com> | 2025-04-20 11:57:40 +0200 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-05-08 16:07:08 +0100 |
| commit | 84e91262d6b94d35b381d0a46ff5402eaac7c996 (patch) | |
| tree | d9ef2bb59247b8e9485ab3e0fd612f113454c104 | |
| parent | 384cdf0f7a2c8d1793b120d82a1584776c064f44 (diff) | |
Fixed #36295, Refs #24305 -- Allowed overriding GenericForeignKey fields on abstract models.
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | django/db/models/base.py | 7 | ||||
| -rw-r--r-- | tests/model_inheritance/test_abstract_inheritance.py | 26 |
3 files changed, 32 insertions, 2 deletions
@@ -34,6 +34,7 @@ answer newbie questions, and generally made Django that much better: Ahmad Alhashemi <trans@ahmadh.com> Ahmad Al-Ibrahim Ahmed Eltawela <https://github.com/ahmedabt> + Ahmed Nassar <https://ahmednassar7.github.io/> ajs <adi@sieker.info> Akash Agrawal <akashrocksha@gmail.com> Akash Kumar Sen <akashkumarsen4@gmail.com> diff --git a/django/db/models/base.py b/django/db/models/base.py index 51aadd935b..34c537fea0 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -348,7 +348,7 @@ class ModelBase(type): new_class._meta.parents.update(base_parents) # Inherit private fields (like GenericForeignKey) from the parent - # class + # class if they are not overridden. for field in base._meta.private_fields: if field.name in field_names: if not base._meta.abstract: @@ -361,7 +361,10 @@ class ModelBase(type): base.__name__, ) ) - else: + elif ( + field.name not in new_class.__dict__ + and field.name not in inherited_attributes + ): field = copy.deepcopy(field) if not base._meta.abstract: field.mti_inherited = True diff --git a/tests/model_inheritance/test_abstract_inheritance.py b/tests/model_inheritance/test_abstract_inheritance.py index 24362292a1..9b9da437da 100644 --- a/tests/model_inheritance/test_abstract_inheritance.py +++ b/tests/model_inheritance/test_abstract_inheritance.py @@ -184,6 +184,32 @@ class AbstractInheritanceTests(SimpleTestCase): ExtendModelAbstract._meta.get_field("field"), GenericRelation ) + def test_override_private_field_with_attr(self): + class AbstractBase(models.Model): + content_type = models.ForeignKey( + ContentType, on_delete=models.SET_NULL, null=True, blank=True + ) + object_id = models.PositiveIntegerField(null=True, blank=True) + related_object = GenericForeignKey("content_type", "object_id") + + class Meta: + abstract = True + + class Descendant(AbstractBase): + related_object = None + + class Mixin: + related_object = None + + class MultiDescendant(Mixin, AbstractBase): + pass + + with self.assertRaises(FieldDoesNotExist): + Descendant._meta.get_field("related_object") + + with self.assertRaises(FieldDoesNotExist): + MultiDescendant._meta.get_field("related_object") + def test_cannot_override_indirect_abstract_field(self): class AbstractBase(models.Model): name = models.CharField(max_length=30) |
