#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Type: Bug
Status: new | Component: Database
| layer (models, ORM)
Version: 5.2 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Attempting to override a GenericForeignKey field in an inherited abstract
model does not work as expected. According to the
[
https://docs.djangoproject.com/en/5.2/topics/db/models/#field-name-
hiding-is-not-permitted 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 [
https://github.com/pandafy/django-genericforeignkey-
inheritance Django project] for quick testing.
**Steps to replicate:**
1. Define an abstract model with a GenericForeignKey field.
2. Create another abstract model that inherits from the first and attempt
to override the GenericForeignKey field by setting it to None.
3. 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, but
`GenericForeignKey` 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:
*
https://docs.djangoproject.com/en/5.1/ref/contrib/contenttypes/
*
https://docs.djangoproject.com/en/5.2/topics/db/models/#field-name-
hiding-is-not-permitted
--
Ticket URL: <
https://code.djangoproject.com/ticket/36295>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.