1
0
mirror of https://github.com/django/django.git synced 2025-05-20 22:06:30 +00:00

Fixed #36295, Refs #24305 -- Allowed overriding GenericForeignKey fields on abstract models.

This commit is contained in:
Ahmed Nassar 2025-04-20 11:57:40 +02:00 committed by Sarah Boyce
parent 384cdf0f7a
commit 84e91262d6
3 changed files with 32 additions and 2 deletions

View File

@ -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>

View File

@ -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

View File

@ -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)