Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #19870 -- Regression in select_related in inheritance cases

There was a regression in case two models inherited the same parent,
and one contained a foreign key to other. When select_related travelled
the foreign key the other model reused the parent join made by the
first model. This was likely caused by Query.join_parent_model()
addition in commit 68985db.

Thanks to Trac alias loic84 for report & tests.
  • Loading branch information...
commit 3c6318e831658b88ba7c3e04f315329071b25e34 1 parent 6491189
@akaariai akaariai authored
View
13 django/db/models/sql/compiler.py
@@ -265,14 +265,19 @@ def get_default_columns(self, with_aliases=False, col_aliases=None,
qn2 = self.connection.ops.quote_name
aliases = set()
only_load = self.deferred_to_columns()
- seen = self.query.included_inherited_models.copy()
- if start_alias:
- seen[None] = start_alias
+ if not start_alias:
+ start_alias = self.query.get_initial_alias()
+ # The 'seen_models' is used to optimize checking the needed parent
+ # alias for a given field. This also includes None -> start_alias to
+ # be used by local fields.
+ seen_models = {None: start_alias}
+
for field, model in opts.get_fields_with_model():
if from_parent and model is not None and issubclass(from_parent, model):
# Avoid loading data for already loaded parents.
continue
- alias = self.query.join_parent_model(opts, model, start_alias, seen)
+ alias = self.query.join_parent_model(opts, model, start_alias,
+ seen_models)
table = self.query.alias_map[alias].table_name
if table in only_load and field.column not in only_load[table]:
continue
View
14 tests/regressiontests/select_related_regress/models.py
@@ -94,3 +94,17 @@ class Item(models.Model):
def __str__(self):
return self.name
+
+# Models for testing bug #19870.
+@python_2_unicode_compatible
+class Fowl(models.Model):
+ name = models.CharField(max_length=10)
+
+ def __str__(self):
+ return self.name
+
+class Hen(Fowl):
+ pass
+
+class Chick(Fowl):
+ mother = models.ForeignKey(Hen)
View
13 tests/regressiontests/select_related_regress/tests.py
@@ -5,7 +5,7 @@
from .models import (Building, Child, Device, Port, Item, Country, Connection,
ClientStatus, State, Client, SpecialClient, TUser, Person, Student,
- Organizer, Class, Enrollment)
+ Organizer, Class, Enrollment, Hen, Chick)
class SelectRelatedRegressTests(TestCase):
@@ -162,3 +162,14 @@ def test_null_join_promotion(self):
# The select_related join was promoted as there is already an
# existing join.
self.assertTrue('LEFT OUTER' in str(qs.query))
+
+ def test_regression_19870(self):
+ """
+ Regression for #19870
+
+ """
+ hen = Hen.objects.create(name='Hen')
+ chick = Chick.objects.create(name='Chick', mother=hen)
+
+ self.assertEqual(Chick.objects.all()[0].mother.name, 'Hen')
+ self.assertEqual(Chick.objects.select_related()[0].mother.name, 'Hen')
Please sign in to comment.
Something went wrong with that request. Please try again.