summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobwa <robwa@users.noreply.github.com>2018-03-13 03:42:48 +0100
committerTim Graham <timograham@gmail.com>2018-03-12 22:42:48 -0400
commit4ab027b94409e6415b774797bf9d3593da9d9ea8 (patch)
tree03c9c8d5c2906658877cbb848c013a9bb1036cc7
parentb639bcc2503d66870f72bdffc01abc015a548462 (diff)
Fixed #28988 -- Fixed queries when a GenericRelation is used with multi-table inheritance.
-rw-r--r--django/contrib/contenttypes/fields.py8
-rw-r--r--django/db/models/base.py4
-rw-r--r--tests/generic_relations_regress/models.py2
-rw-r--r--tests/generic_relations_regress/tests.py10
4 files changed, 22 insertions, 2 deletions
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py
index d186e1f39a..e55766aa6f 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -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
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 20d1c73ddf..9af6a8f92d 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -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.
diff --git a/tests/generic_relations_regress/models.py b/tests/generic_relations_regress/models.py
index c9572eb961..5d8716aa0c 100644
--- a/tests/generic_relations_regress/models.py
+++ b/tests/generic_relations_regress/models.py
@@ -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):
diff --git a/tests/generic_relations_regress/tests.py b/tests/generic_relations_regress/tests.py
index 91158d8198..769a64d0f1 100644
--- a/tests/generic_relations_regress/tests.py
+++ b/tests/generic_relations_regress/tests.py
@@ -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])