Author: mtredinnick Date: 2009-03-24 00:54:35 -0500 (Tue, 24 Mar 2009) New Revision: 10138
Modified: django/branches/releases/1.0.X/django/db/models/sql/query.py django/branches/releases/1.0.X/tests/regressiontests/queries/models.py django/branches/releases/1.0.X/tests/regressiontests/select_related_regress/models.py Log: [1.0.X] Fixed #9926 -- Fixes for some select_related() situations. Using select_related(...) across a nullable relation to a multi-table model inheritance situation no longer excludes results. Thanks to AdamG for a test demonstrating part of the problem. Backport of r10136 from trunk. Modified: django/branches/releases/1.0.X/django/db/models/sql/query.py =================================================================== --- django/branches/releases/1.0.X/django/db/models/sql/query.py 2009-03-24 04:26:56 UTC (rev 10137) +++ django/branches/releases/1.0.X/django/db/models/sql/query.py 2009-03-24 05:54:35 UTC (rev 10138) @@ -510,6 +510,7 @@ alias = self.included_inherited_models[model] if as_pairs: result.append((alias, field.column)) + aliases.add(alias) continue if with_aliases and field.column in col_aliases: c_alias = 'Col%d' % len(col_aliases) @@ -524,7 +525,7 @@ if with_aliases: col_aliases.add(field.column) if as_pairs: - return result, None + return result, aliases return result, aliases def get_from_clause(self): @@ -1076,6 +1077,7 @@ if model: int_opts = opts alias = root_alias + alias_chain = [] for int_model in opts.get_base_chain(model): lhs_col = int_opts.parents[int_model].column dedupe = lhs_col in opts.duplicate_targets @@ -1087,8 +1089,11 @@ alias = self.join((alias, int_opts.db_table, lhs_col, int_opts.pk.column), exclusions=used, promote=promote) + alias_chain.append(alias) for (dupe_opts, dupe_col) in dupe_set: self.update_dupe_avoidance(dupe_opts, dupe_col, alias) + if self.alias_map[root_alias][JOIN_TYPE] == self.LOUTER: + self.promote_alias_chain(alias_chain, True) else: alias = root_alias @@ -1102,8 +1107,11 @@ f.rel.get_related_field().column), exclusions=used.union(avoid), promote=promote) used.add(alias) - self.related_select_cols.extend(self.get_default_columns( - start_alias=alias, opts=f.rel.to._meta, as_pairs=True)[0]) + columns, aliases = self.get_default_columns(start_alias=alias, + opts=f.rel.to._meta, as_pairs=True) + self.related_select_cols.extend(columns) + if self.alias_map[alias][JOIN_TYPE] == self.LOUTER: + self.promote_alias_chain(aliases, True) self.related_select_fields.extend(f.rel.to._meta.fields) if restricted: next = requested.get(f.name, {}) Modified: django/branches/releases/1.0.X/tests/regressiontests/queries/models.py =================================================================== --- django/branches/releases/1.0.X/tests/regressiontests/queries/models.py 2009-03-24 04:26:56 UTC (rev 10137) +++ django/branches/releases/1.0.X/tests/regressiontests/queries/models.py 2009-03-24 05:54:35 UTC (rev 10138) @@ -16,10 +16,17 @@ except NameError: from django.utils.itercompat import sorted +class DumbCategory(models.Model): + pass + +class NamedCategory(DumbCategory): + name = models.CharField(max_length=10) + class Tag(models.Model): name = models.CharField(max_length=10) parent = models.ForeignKey('self', blank=True, null=True, related_name='children') + category = models.ForeignKey(NamedCategory, null=True, default=None) class Meta: ordering = ['name'] @@ -266,8 +273,9 @@ __test__ = {'API_TESTS':""" ->>> t1 = Tag.objects.create(name='t1') ->>> t2 = Tag.objects.create(name='t2', parent=t1) +>>> generic = NamedCategory.objects.create(name="Generic") +>>> t1 = Tag.objects.create(name='t1', category=generic) +>>> t2 = Tag.objects.create(name='t2', parent=t1, category=generic) >>> t3 = Tag.objects.create(name='t3', parent=t1) >>> t4 = Tag.objects.create(name='t4', parent=t3) >>> t5 = Tag.objects.create(name='t5', parent=t3) @@ -726,6 +734,12 @@ >>> Tag.objects.select_related('parent').order_by('name') [<Tag: t1>, <Tag: t2>, <Tag: t3>, <Tag: t4>, <Tag: t5>] +Bug #9926 +>>> Tag.objects.select_related("parent", "category").order_by('name') +[<Tag: t1>, <Tag: t2>, <Tag: t3>, <Tag: t4>, <Tag: t5>] +>>> Tag.objects.select_related('parent', "parent__category").order_by('name') +[<Tag: t1>, <Tag: t2>, <Tag: t3>, <Tag: t4>, <Tag: t5>] + Bug #6180, #6203 -- dates with limits and/or counts >>> Item.objects.count() 4 Modified: django/branches/releases/1.0.X/tests/regressiontests/select_related_regress/models.py =================================================================== --- django/branches/releases/1.0.X/tests/regressiontests/select_related_regress/models.py 2009-03-24 04:26:56 UTC (rev 10137) +++ django/branches/releases/1.0.X/tests/regressiontests/select_related_regress/models.py 2009-03-24 05:54:35 UTC (rev 10138) @@ -65,6 +65,23 @@ state = models.ForeignKey(State, null=True) status = models.ForeignKey(ClientStatus) +# Some model inheritance exercises +class Parent(models.Model): + name = models.CharField(max_length=10) + + def __unicode__(self): + return self.name + +class Child(Parent): + value = models.IntegerField() + +class Item(models.Model): + name = models.CharField(max_length=10) + child = models.ForeignKey(Child, null=True) + + def __unicode__(self): + return self.name + __test__ = {'API_TESTS': """ Regression test for bug #7110. When using select_related(), we must query the Device and Building tables using two different aliases (each) in order to @@ -140,4 +157,12 @@ <ClientStatus: ClientStatus object> >>> Client.objects.select_related('status')[0].status <ClientStatus: ClientStatus object> + +Exercising select_related() with multi-table model inheritance. +>>> c1 = Child.objects.create(name="child1", value=42) +>>> _ = Item.objects.create(name="item1", child=c1) +>>> _ = Item.objects.create(name="item2") +>>> Item.objects.select_related("child").order_by("name") +[<Item: item1>, <Item: item2>] + """} --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-updates@googlegroups.com To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-updates?hl=en -~----------~----~----~----~------~----~------~--~---