[Django] #36295: Unable to Override GenericForeignKey in Inherited Abstract Class

19 views
Skip to first unread message

Django

unread,
Apr 3, 2025, 7:37:08 AMApr 3
to django-...@googlegroups.com
#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.

Django

unread,
Apr 3, 2025, 10:48:46 AMApr 3
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: 5.2
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* stage: Unreviewed => Accepted

Comment:

Thank you!
Using the models as defined above, I was able to replicate

{{{#!diff
diff --git a/tests/generic_relations/tests.py
b/tests/generic_relations/tests.py
index e0c6fe2db7..c4163f3c87 100644
--- a/tests/generic_relations/tests.py
+++ b/tests/generic_relations/tests.py
@@ -1,6 +1,6 @@
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.prefetch import GenericPrefetch
-from django.core.exceptions import FieldError
+from django.core.exceptions import FieldError, FieldDoesNotExist
from django.db.models import Q, prefetch_related_objects
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature

@@ -9,6 +9,7 @@ from .models import (
Animal,
Carrot,
Comparison,
+ ConcreteEntity,
ConcreteRelatedModel,
ForConcreteModelModel,
ForProxyModelModel,
@@ -780,6 +781,12 @@ class GenericRelationsTests(TestCase):
self.platypus.latin_name,
)

+ def test_overwriting_generic_fk(self):
+ with self.assertRaises(FieldDoesNotExist):
+ ConcreteEntity._meta.get_field('description')
+ with self.assertRaises(FieldDoesNotExist):
+ ConcreteEntity._meta.get_field('related_object')
+

class ProxyRelatedModelTest(TestCase):
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:1>

Django

unread,
Apr 3, 2025, 10:49:18 AMApr 3
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
--------------------------------------+------------------------------------
Reporter: Gagan Deep | Owner: (none)
Type: Bug | Status: new
Component: contrib.contenttypes | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Sarah Boyce):

* component: Database layer (models, ORM) => contrib.contenttypes

--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:2>

Django

unread,
Apr 3, 2025, 1:08:44 PMApr 3
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
--------------------------------------+------------------------------------
Reporter: Gagan Deep | Owner: (none)
Type: Bug | Status: new
Component: contrib.contenttypes | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Comment (by Gagan Deep):

Hello Sarah! Can I get some pointers how can I approach to solve this
issue? I would like to attempt a fix.
--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:3>

Django

unread,
Apr 4, 2025, 11:20:39 AMApr 4
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
--------------------------------------+------------------------------------
Reporter: Gagan Deep | Owner: (none)
Type: Bug | Status: new
Component: contrib.contenttypes | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Comment (by Senthil Kumar):

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!
--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:4>

Django

unread,
Apr 7, 2025, 4:43:40 AMApr 7
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Ahmed Nassar):

* owner: (none) => Ahmed Nassar
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:5>

Django

unread,
Apr 20, 2025, 6:01:25 AMApr 20
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Ahmed Nassar):

* has_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:6>

Django

unread,
Apr 26, 2025, 12:54:38 PMApr 26
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Arne):

The PR looks fine to me. Just waiting for some minor, optional adjustments
before _ready for checkin_.
--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:7>

Django

unread,
Apr 26, 2025, 2:27:41 PMApr 26
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Arne):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:8>

Django

unread,
May 5, 2025, 8:46:43 AMMay 5
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Ahmed Nassar):

Can anyone review? Looking forward to merging this PR.
--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:9>

Django

unread,
May 8, 2025, 7:30:57 AMMay 8
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* needs_better_patch: 0 => 1
* stage: Ready for checkin => Accepted

--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:10>

Django

unread,
May 8, 2025, 7:53:04 AMMay 8
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Ahmed Nassar):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:11>

Django

unread,
May 8, 2025, 8:35:54 AMMay 8
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: assigned
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:12>

Django

unread,
May 8, 2025, 11:07:22 AMMay 8
to django-...@googlegroups.com
#36295: Unable to Override GenericForeignKey in Inherited Abstract Class
-------------------------------------+-------------------------------------
Reporter: Gagan Deep | Owner: Ahmed
| Nassar
Type: Bug | Status: closed
Component: | Version: 5.2
contrib.contenttypes |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce <42296566+sarahboyce@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"84e91262d6b94d35b381d0a46ff5402eaac7c996" 84e91262]:
{{{#!CommitTicketReference repository=""
revision="84e91262d6b94d35b381d0a46ff5402eaac7c996"
Fixed #36295, Refs #24305 -- Allowed overriding GenericForeignKey fields
on abstract models.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36295#comment:13>
Reply all
Reply to author
Forward
0 new messages