From 38e24d680d28b92997def9ab46a961d09bb81dce Mon Sep 17 00:00:00 2001 From: pegler Date: Thu, 5 Dec 2013 11:46:25 -0500 Subject: [PATCH] Fixed #21554 -- Incorrect SQL generated when using multiple inheritance. --- django/db/models/sql/compiler.py | 19 +++++++++++++------ tests/model_inheritance_regress/models.py | 14 ++++++++++++++ tests/model_inheritance_regress/tests.py | 9 ++++++++- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 98b953937f2..7e48adb1d6b 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -284,25 +284,32 @@ class SQLCompiler(object): continue alias = self.query.join_parent_model(opts, model, start_alias, seen_models) + column = field.column + for seen_model, seen_alias in seen_models.items(): + if seen_model and seen_alias == alias: + ancestor_link = seen_model._meta.get_ancestor_link(model) + if ancestor_link: + column = ancestor_link.column + break table = self.query.alias_map[alias].table_name - if table in only_load and field.column not in only_load[table]: + if table in only_load and column not in only_load[table]: continue if as_pairs: - result.append((alias, field.column)) + result.append((alias, column)) aliases.add(alias) continue - if with_aliases and field.column in col_aliases: + if with_aliases and column in col_aliases: c_alias = 'Col%d' % len(col_aliases) result.append('%s.%s AS %s' % (qn(alias), - qn2(field.column), c_alias)) + qn2(column), c_alias)) col_aliases.add(c_alias) aliases.add(c_alias) else: - r = '%s.%s' % (qn(alias), qn2(field.column)) + r = '%s.%s' % (qn(alias), qn2(column)) result.append(r) aliases.add(r) if with_aliases: - col_aliases.add(field.column) + col_aliases.add(column) return result, aliases def get_distinct(self): diff --git a/tests/model_inheritance_regress/models.py b/tests/model_inheritance_regress/models.py index 53752b69487..cb0b2fe72f5 100644 --- a/tests/model_inheritance_regress/models.py +++ b/tests/model_inheritance_regress/models.py @@ -233,3 +233,17 @@ class User(models.Model): class Profile(User): profile_id = models.AutoField(primary_key=True) extra = models.CharField(max_length=30, blank=True) + + +# Check concrete + concrete -> concrete -> concrete +class Politician(models.Model): + politician_id = models.AutoField(primary_key=True) + title = models.CharField(max_length=50) + + +class Congressman(Person, Politician): + state = models.CharField(max_length=2) + + +class Senator(Congressman): + pass diff --git a/tests/model_inheritance_regress/tests.py b/tests/model_inheritance_regress/tests.py index 95c693ddd8a..3664fc8c04a 100644 --- a/tests/model_inheritance_regress/tests.py +++ b/tests/model_inheritance_regress/tests.py @@ -15,7 +15,7 @@ from .models import (Place, Restaurant, ItalianRestaurant, ParkingLot, SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM, Person, BirthdayParty, BachelorParty, MessyBachelorParty, InternalCertificationAudit, BusStation, TrainStation, User, Profile, - ParkingLot4A, ParkingLot4B) + ParkingLot4A, ParkingLot4B, Senator) class ModelInheritanceTest(TestCase): @@ -455,3 +455,10 @@ class ModelInheritanceTest(TestCase): # used in the qs and top contains direct pointer to the bottom model. qs = ItalianRestaurant.objects.values_list('serves_gnocchi').filter(name='foo') self.assertEqual(str(qs.query).count('JOIN'), 1) + + def test_issue_21554(self): + senator = Senator.objects.create( + name='John Doe', title='X', state='Y' + ) + + Senator.objects.get(pk=senator.pk)