8000 Fixed #36295, Refs #24305 -- Allowed overriding GenericForeignKey fie… · feanil/django@84e9126 · GitHub
[go: up one dir, main page]

Skip to content

Commit 84e9126

Browse files
AhmedNassar7sarahboyce
authored andcommitted
Fixed #36295, Refs #24305 -- Allowed overriding GenericForeignKey fields on abstract models.
1 parent 384cdf0 commit 84e9126

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ answer newbie questions, and generally made Django that much better:
3434
Ahmad Alhashemi <trans@ahmadh.com>
3535
Ahmad Al-Ibrahim
3636
Ahmed Eltawela <https://github.com/ahmedabt>
37+
Ahmed Nassar <https://ahmednassar7.github.io/>
3738
ajs <adi@sieker.info>
3839
Akash Agrawal <akashrocksha@gmail.com>
3940
Akash Kumar Sen <akashkumarsen4@gmail.com>

django/db/models/base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ def __new__(cls, name, bases, attrs, **kwargs):
348348
new_class._meta.parents.update(base_parents)
349349

350350
# Inherit private fields (like GenericForeignKey) from the parent
351-
# class
351+
# class if they are not overridden.
352352
for field in base._meta.private_fields:
353353
if field.name in field_names:
354354
if not base._meta.abstract:
@@ -361,7 +361,10 @@ def __new__(cls, name, bases, attrs, **kwargs):
361361
base.__name__,
362362
)
363363
)
364-
else:
364+
elif (
365+
field.name not in new_class.__dict__
366+
and field.name not in inherited_attributes
367+
):
365368
field = copy.deepcopy(field)
366369
if not base._meta.abstract:
367370
field.mti_inherited = True

tests/model_inheritance/test_abstract_inheritance.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,32 @@ class ExtendModelAbstract(ModelAbstract):
184184
ExtendModelAbstract._meta.get_field("field"), GenericRelation
185185
)
186186

187+
def test_override_private_field_with_attr(self):
188+
class AbstractBase(models.Model):
189+
content_type = models.ForeignKey(
190+
ContentType, on_delete=models.SET_NULL, null=True, blank=True
191+
)
192+
object_id = models.PositiveIntegerField(null=True, blank=True)
193+
related_object = GenericForeignKey("content_type", "object_id")
194+
195+
class Meta:
196+
abstract = True
197+
198+
class Descendant(AbstractBase):
199+
related_object = None
200+
201+
class Mixin:
202+
related_object = None
203+
204+
class MultiDescendant(Mixin, AbstractBase):
205+
pass
206+
207+
with self.assertRaises(FieldDoesNotExist):
208+
Descendant._meta.get_field("related_object")
209+
210+
with self.assertRaises(FieldDoesNotExist):
211+
MultiDescendant._meta.get_field("related_object")
212+
187213
def test_cannot_override_indirect_abstract_field(self):
188214
class AbstractBase(models.Model):
189215
name = models.CharField(max_length=30)

0 commit comments

Comments
 (0)
0