[Django] #28988: Multi-table inheritance breaks GenericRelation querying

18 views
Skip to first unread message

Django

unread,
Jan 4, 2018, 11:29:28 AM1/4/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
-----------------------------------------+------------------------
Reporter: robwa | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.11
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 |
-----------------------------------------+------------------------
Minimal example to reproduce. Create two models:

{{{
#!python
class Generic(models.Model):
content_type = models.ForeignKey('contenttypes.ContentType')
object_id = models.PositiveIntegerField()
obj = GenericForeignKey()

class Vehicle(models.Model):
associations = GenericRelation('Generic',
related_query_name='vehicles')
}}}

Create a `Vehicle` and a `Generic` object pointing to the `Vehicle`. The
following query returns the expected result:

{{{
In [2]: Generic.objects.filter(vehicles__id=1)
Out[2]: <QuerySet [<Generic: Generic object>]>
}}}

Add a third model. Don't change any data. Now the query returns an empty
query set:

{{{
#!python
class Bike(Vehicle):
pass
}}}

{{{
In [2]: Generic.objects.filter(vehicles__id=1)
Out[2]: <QuerySet []>
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28988>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jan 5, 2018, 11:58:03 AM1/5/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: nobody
Type: Bug | Status: new
Component: contrib.contenttypes | Version: 1.11
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 Tim Graham):

* type: Uncategorized => Bug
* component: Uncategorized => contrib.contenttypes
* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:1>

Django

unread,
Jan 9, 2018, 1:35:28 PM1/9/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: Paulo
Type: Bug | Status: assigned

Component: contrib.contenttypes | Version: 1.11
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 Paulo):

* owner: nobody => Paulo
* status: new => assigned


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

Django

unread,
Jan 18, 2018, 7:32:10 AM1/18/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: Paulo
Type: Bug | Status: assigned
Component: contrib.contenttypes | Version: 1.11
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 robwa):

I'm not sure if this is helpful, but I found

{{{
In [44]: Generic._meta.get_field('vehicles').field.model
Out[44]: foo.models.Bike
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:3>

Django

unread,
Jan 19, 2018, 5:25:07 AM1/19/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: Paulo
Type: Bug | Status: assigned
Component: contrib.contenttypes | Version: 1.11
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 robwa):

Now I can see why this happens:

* `GenericRelation` fields are created as ''private fields''.
* ''Private fields'' are explicitly inherited by child classes
([https://github.com/django/django/blob/649d5eaa8b7b224fc0eb8a3339a589288d5b10e8/django/db/models/base.py#L290
db.models.base]).
* When constructing the relation tree, ''private fields'' are included
([https://github.com/django/django/blob/649d5eaa8b7b224fc0eb8a3339a589288d5b10e8/django/db/models/options.py#L858
db.models.options]).
* When constructing the fields map, relations to ''private fields'' of
child classes simply overwrite the relations to the parents
([https://github.com/django/django/blob/649d5eaa8b7b224fc0eb8a3339a589288d5b10e8/django/db/models/options.py#L586
db.models.options]).

Where is the point to fix this?

--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:4>

Django

unread,
Jan 19, 2018, 6:39:05 AM1/19/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: Paulo
Type: Bug | Status: assigned
Component: contrib.contenttypes | Version: 1.11
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 robwa):

Maybe the ''reverse relationship'' should be removed from
`GenericRelation`s when copying them to child classes.

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

Django

unread,
Jan 22, 2018, 6:44:22 PM1/22/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: Paulo
Type: Bug | Status: assigned
Component: contrib.contenttypes | Version: 1.11
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 Paulo):

I think the behavior should be consistent with how a normal ForeignKey
field behaves in multi-table inheritance.
In the following scenario:


{{{
class Car(models.Model):
owner = models.ForeignKey(Owner, related_name='cars')
some_id = models.CharField(max_length=100)

class Car2(Car):
pass
}}}


Running
{{{
Owner.objects.filter(cars__isnull=True)
}}}


Will output:

{{{
SELECT "paulotest_owner"."id",
"paulotest_owner"."nick"
FROM "paulotest_owner"
LEFT OUTER JOIN "paulotest_car" ON ("paulotest_owner"."id" =
"paulotest_car"."owner_id")
WHERE "paulotest_car"."id" IS NULL
}}}

So we should prevent the reverse relationship from being set.

@Robert, if you would like to work on this, I can un-assign it, I'm
planning to tackle it within the next two weeks.

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

Django

unread,
Jan 26, 2018, 4:22:44 AM1/26/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: robwa

Type: Bug | Status: assigned
Component: contrib.contenttypes | Version: 1.11
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 robwa):

* owner: Paulo => robwa


Comment:

@Paulo, I will try to work on this. If I come up with a patch, I'd like to
discuss it with you, as I'm not very familiar with the django model
internals.

--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:7>

Django

unread,
Jan 26, 2018, 6:02:10 AM1/26/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: robwa
Type: Bug | Status: assigned
Component: contrib.contenttypes | Version: 1.11
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 robwa):

* has_patch: 0 => 1


Comment:

Added a [https://github.com/django/django/pull/9624 pull request].

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

Django

unread,
Feb 22, 2018, 5:38:29 AM2/22/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: robwa
Type: Bug | Status: assigned
Component: contrib.contenttypes | Version: 1.11
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 Carlton Gibson):

* needs_better_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:9>

Django

unread,
Feb 22, 2018, 5:39:51 AM2/22/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: (none)
Type: Bug | Status: new

Component: contrib.contenttypes | Version: 1.11
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 robwa):

* owner: robwa => (none)
* status: assigned => new


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

Django

unread,
Feb 23, 2018, 4:38:53 AM2/23/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
--------------------------------------+------------------------------------
Reporter: robwa | Owner: (none)
Type: Bug | Status: new
Component: contrib.contenttypes | Version: 1.11
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
--------------------------------------+------------------------------------

Comment (by robwa):

Updated the [https://github.com/django/django/pull/9624 PR].

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

Django

unread,
Mar 9, 2018, 3:17:44 AM3/9/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
-------------------------------------+-------------------------------------

Reporter: robwa | Owner: (none)
Type: Bug | Status: new
Component: | Version: 1.11
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 Carlton Gibson):

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


Comment:

Updated changes look good.

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

Django

unread,
Mar 12, 2018, 10:43:15 PM3/12/18
to django-...@googlegroups.com
#28988: Multi-table inheritance breaks GenericRelation querying
-------------------------------------+-------------------------------------
Reporter: robwa | Owner: Tim
| Graham <timograham@…>
Type: Bug | Status: closed
Component: | Version: 1.11
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 Tim Graham <timograham@…>):

* status: new => closed
* owner: (none) => Tim Graham <timograham@…>
* resolution: => fixed


Comment:

In [changeset:"4ab027b94409e6415b774797bf9d3593da9d9ea8" 4ab027b]:
{{{
#!CommitTicketReference repository=""
revision="4ab027b94409e6415b774797bf9d3593da9d9ea8"
Fixed #28988 -- Fixed queries when a GenericRelation is used with multi-
table inheritance.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:13>

Reply all
Reply to author
Forward
0 new messages