From 415ffa8df56d72bf6f114abc8fdae11d459e768d Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Sat, 28 Feb 2009 02:59:40 +0000 Subject: [PATCH] Fixed #10028 -- Fixed a problem when ordering by related models. Some results were inadvertently being excluded if we were ordering across a nullable relation which itself ordering by a non-nullable relation. git-svn-id: http://code.djangoproject.com/svn/django/trunk@9916 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/sql/query.py | 7 +++--- tests/regressiontests/queries/models.py | 31 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index af9d173f4c5..ac100c06e58 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -716,7 +716,7 @@ class BaseQuery(object): result, params = [], [] if self.group_by is not None: group_by = self.group_by or [] - + extra_selects = [] for extra_select, extra_params in self.extra_select.itervalues(): extra_selects.append(extra_select) @@ -834,8 +834,9 @@ class BaseQuery(object): # the model. self.ref_alias(alias) - # Must use left outer joins for nullable fields. - self.promote_alias_chain(joins) + # Must use left outer joins for nullable fields and their relations. + self.promote_alias_chain(joins, + self.alias_map[joins[0]][JOIN_TYPE] == self.LOUTER) # If we get to this point and the field is a relation to another model, # append the default ordering for that model. diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index e8cf6456330..a4182c6c906 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -238,6 +238,32 @@ class PointerA(models.Model): class PointerB(models.Model): connection = models.ForeignKey(SharedConnection) +# Multi-layer ordering +class SingleObject(models.Model): + name = models.CharField(max_length=10) + + class Meta: + ordering = ['name'] + + def __unicode__(self): + return self.name + +class RelatedObject(models.Model): + single = models.ForeignKey(SingleObject) + + class Meta: + ordering = ['single'] + +class Plaything(models.Model): + name = models.CharField(max_length=10) + others = models.ForeignKey(RelatedObject, null=True) + + class Meta: + ordering = ['others'] + + def __unicode__(self): + return self.name + __test__ = {'API_TESTS':""" >>> t1 = Tag.objects.create(name='t1') @@ -1044,6 +1070,11 @@ Bug #9985 -- qs.values_list(...).values(...) combinations should work. >>> Annotation.objects.filter(notes__in=Note.objects.filter(note="n1").values_list('note').values('id')) [] +Bug #10028 -- ordering by model related to nullable relations(!) should use +outer joins, so that all results are included. +>>> _ = Plaything.objects.create(name="p1") +>>> Plaything.objects.all() +[] """} # In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__