{{{
#!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.
* type: Uncategorized => Bug
* component: Uncategorized => contrib.contenttypes
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:1>
* owner: nobody => Paulo
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:2>
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>
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>
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>
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>
* 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>
* 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>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:9>
* owner: robwa => (none)
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:10>
Comment (by robwa):
Updated the [https://github.com/django/django/pull/9624 PR].
--
Ticket URL: <https://code.djangoproject.com/ticket/28988#comment:11>
* 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>
* 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>