Fixed #28988 -- Fixed queries when a GenericRelation is used with multi-table inheritance.
This commit is contained in:
parent
b639bcc250
commit
4ab027b944
|
@ -283,6 +283,8 @@ class GenericRelation(ForeignObject):
|
|||
|
||||
rel_class = GenericRel
|
||||
|
||||
mti_inherited = False
|
||||
|
||||
def __init__(self, to, object_id_field='object_id', content_type_field='content_type',
|
||||
for_concrete_model=True, related_query_name=None, limit_choices_to=None, **kwargs):
|
||||
kwargs['rel'] = self.rel_class(
|
||||
|
@ -427,6 +429,12 @@ class GenericRelation(ForeignObject):
|
|||
kwargs['private_only'] = True
|
||||
super().contribute_to_class(cls, name, **kwargs)
|
||||
self.model = cls
|
||||
# Disable the reverse relation for fields inherited by subclasses of a
|
||||
# model in multi-table inheritance. The reverse relation points to the
|
||||
# field of the base model.
|
||||
if self.mti_inherited:
|
||||
self.remote_field.related_name = '+'
|
||||
self.remote_field.related_query_name = None
|
||||
setattr(cls, self.name, ReverseGenericManyToOneDescriptor(self.remote_field))
|
||||
|
||||
# Add get_RELATED_order() and set_RELATED_order() to the model this
|
||||
|
|
|
@ -278,7 +278,9 @@ class ModelBase(type):
|
|||
)
|
||||
)
|
||||
else:
|
||||
new_class.add_to_class(field.name, copy.deepcopy(field))
|
||||
field = copy.deepcopy(field)
|
||||
field.mti_inherited = True
|
||||
new_class.add_to_class(field.name, field)
|
||||
|
||||
# Copy indexes so that index names are unique when models extend an
|
||||
# abstract model.
|
||||
|
|
|
@ -26,7 +26,7 @@ class LinkProxy(Link):
|
|||
|
||||
class Place(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
links = GenericRelation(Link)
|
||||
links = GenericRelation(Link, related_query_name='places')
|
||||
link_proxy = GenericRelation(LinkProxy)
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -263,3 +263,13 @@ class GenericRelationTests(TestCase):
|
|||
place = Place.objects.create()
|
||||
Link.objects.create(content_object=place)
|
||||
self.assertEqual(Place.objects.get(link_proxy__object_id=place.id), place)
|
||||
|
||||
def test_generic_reverse_relation_with_mti(self):
|
||||
"""
|
||||
Filtering with a reverse generic relation, where the GenericRelation
|
||||
comes from multi-table inheritance.
|
||||
"""
|
||||
place = Place.objects.create(name='Test Place')
|
||||
link = Link.objects.create(content_object=place)
|
||||
result = Link.objects.filter(places=place)
|
||||
self.assertCountEqual(result, [link])
|
||||
|
|
Loading…
Reference in New Issue