Opened 3 weeks ago
Last modified 4 days ago
#36295 assigned Bug
Unable to Override GenericForeignKey in Inherited Abstract Class
Description ¶
Attempting to override a GenericForeignKey field in an inherited abstract model does not work as expected. According to the Django documentation, it should be possible to hide a field inherited from an abstract model by setting it to None
.
However, this does not seem to work for GenericForeignKey.
I have created a Django project for quick testing.
Steps to replicate:
- Define an abstract model with a GenericForeignKey field.
- Create another abstract model that inherits from the first and attempt to override the GenericForeignKey field by setting it to None.
- Define a concrete model that inherits from the second abstract model.
Code Example
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models class AbstractBaseModel(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") description = models.TextField(null=True, blank=True) class Meta: abstract = True class AbstractDerivedModel(AbstractBaseModel): related_object = None # Override GenericForeignKey description = None class Meta: abstract = True class ConcreteEntity(AbstractDerivedModel): name = models.CharField(max_length=255) class Meta: abstract = False
Expected Behavior:
The related_object field
in AbstractDerivedModel
should override the GenericForeignKey
in AbstractBaseModel
, making it effectively absent in ConcreteEntity
.
Actual Behavior:
Django still considers the GenericForeignKey field from AbstractBaseModel when defining ConcreteEntity, leading to unexpected behavior.
Additional Notes:
- Overriding standard model fields with
None
works as expected, butGenericForeignKey
does not follow the same behavior (description
field in the above example). - There is no explicit mention in the documentation that GenericForeignKey is exempt from the field-hiding mechanism. I checked the following pages:
According to the ticket's flags, the next step(s) to move this issue forward are:
- For anyone except the patch author to review the patch using the patch review checklist and either mark the ticket as "Ready for checkin" if everything looks good, or leave comments for improvement and mark the ticket as "Patch needs improvement".
Change History (6)
comment:1 by , 3 weeks ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 3 weeks ago
Component: | Database layer (models, ORM) → contrib.contenttypes |
---|
comment:3 by , 3 weeks ago
Hello Sarah! Can I get some pointers how can I approach to solve this issue? I would like to attempt a fix.
comment:4 by , 3 weeks ago
This is my first time working with the Django source code. After reviewing the codebase, I believe the fix below might address the issue. However, I'm unsure whether this is the expected behavior that requires a documentation update or if it's an actual bug.
File db/models/base.py -- line 348
if field.column is not None: # the exact fix field = copy.deepcopy(field) if not base._meta.abstract: field.mti_inherited = True new_class.add_to_class(field.name, field)
Apologies, but I'm unsure how to present this from the codebase. It would be helpful if someone could guide me on how to share the diff, similar to the comments above. Thanks!
comment:5 by , 2 weeks ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:6 by , 4 days ago
Has patch: | set |
---|
Thank you!
Using the models as defined above, I was able to replicate
TabularUnified tests/generic_relations/tests.py