Skip to content

Commit

Permalink
Option 1
Browse files Browse the repository at this point in the history
  • Loading branch information
akaariai committed Jun 10, 2013
1 parent 86cb1b2 commit 62b1d93
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
6 changes: 4 additions & 2 deletions django/db/models/sql/query.py
Expand Up @@ -845,8 +845,8 @@ def join(self, connection, reuse=None, outer_if_first=False,
(matching the connection) are reusable, or it can be a set containing (matching the connection) are reusable, or it can be a set containing
the aliases that can be reused. the aliases that can be reused.
If 'outer_if_first' is True and a new join is created, it will have the If 'outer_if_first' is True and a new join is created (or a join with
LOUTER join type. refcount 0 is reused), it will have the LOUTER join type.
A join is always created as LOUTER if the lhs alias is LOUTER to make A join is always created as LOUTER if the lhs alias is LOUTER to make
sure we do not generate chains like t1 LOUTER t2 INNER t3. sure we do not generate chains like t1 LOUTER t2 INNER t3.
Expand All @@ -870,6 +870,8 @@ def join(self, connection, reuse=None, outer_if_first=False,
# check that the existing join is created using the same # check that the existing join is created using the same
# join_field used for the under work join. # join_field used for the under work join.
continue continue
if self.alias_refcount[alias] == 0 and outer_if_first:
self.promote_joins([alias])
self.ref_alias(alias) self.ref_alias(alias)
return alias return alias


Expand Down
12 changes: 12 additions & 0 deletions tests/select_related_regress/models.py
Expand Up @@ -95,6 +95,18 @@ class Item(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name


class ChildA(models.Model):
parent = models.ForeignKey(Parent)

@python_2_unicode_compatible
class ChildB(models.Model):
name = models.CharField(max_length=10)
parent = models.ForeignKey(Parent, null=True)
child = models.ForeignKey(ChildA, null=True)

def __str__(self):
return self.name

# Models for testing bug #19870. # Models for testing bug #19870.
@python_2_unicode_compatible @python_2_unicode_compatible
class Fowl(models.Model): class Fowl(models.Model):
Expand Down
20 changes: 19 additions & 1 deletion tests/select_related_regress/tests.py
@@ -1,11 +1,12 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals


from django.db import models
from django.test import TestCase from django.test import TestCase
from django.utils import six from django.utils import six


from .models import (Building, Child, Device, Port, Item, Country, Connection, from .models import (Building, Child, Device, Port, Item, Country, Connection,
ClientStatus, State, Client, SpecialClient, TUser, Person, Student, ClientStatus, State, Client, SpecialClient, TUser, Person, Student,
Organizer, Class, Enrollment, Hen, Chick) Organizer, Class, Enrollment, Hen, Chick, Parent, ChildA, ChildB)




class SelectRelatedRegressTests(TestCase): class SelectRelatedRegressTests(TestCase):
Expand Down Expand Up @@ -173,3 +174,20 @@ def test_regression_19870(self):


self.assertEqual(Chick.objects.all()[0].mother.name, 'Hen') self.assertEqual(Chick.objects.all()[0].mother.name, 'Hen')
self.assertEqual(Chick.objects.select_related()[0].mother.name, 'Hen') self.assertEqual(Chick.objects.select_related()[0].mother.name, 'Hen')

def test_ticket_20528(self):
"""
Regression for #20528
Using Qs and select_related with a certain config of ForeignKeys
resulted in incorrect joins.
"""
parent = Parent.objects.create(name="foo")
childA = ChildA.objects.create(parent=parent)
childB = ChildB.objects.create(child=childA, name="Bobby")
queryset = ChildB.objects.filter(
models.Q(parent=parent) | models.Q(child__parent=parent)
)
self.assertQuerysetEqual(queryset, [childB], lambda x: x)
queryset = queryset.select_related('parent')
self.assertQuerysetEqual(queryset, [childB], lambda x: x)

0 comments on commit 62b1d93

Please sign in to comment.