Permalink
Browse files

Option 1

  • Loading branch information...
1 parent 86cb1b2 commit 62b1d93d638ae05312af77775c96bdd602f075a5 @akaariai committed Jun 10, 2013
Showing with 35 additions and 3 deletions.
  1. +4 −2 django/db/models/sql/query.py
  2. +12 −0 tests/select_related_regress/models.py
  3. +19 −1 tests/select_related_regress/tests.py
@@ -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
the aliases that can be reused.
- If 'outer_if_first' is True and a new join is created, it will have the
- LOUTER join type.
+ If 'outer_if_first' is True and a new join is created (or a join with
+ 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
sure we do not generate chains like t1 LOUTER t2 INNER t3.
@@ -870,6 +870,8 @@ def join(self, connection, reuse=None, outer_if_first=False,
# check that the existing join is created using the same
# join_field used for the under work join.
continue
+ if self.alias_refcount[alias] == 0 and outer_if_first:
+ self.promote_joins([alias])
self.ref_alias(alias)
return alias
@@ -95,6 +95,18 @@ class Item(models.Model):
def __str__(self):
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.
@python_2_unicode_compatible
class Fowl(models.Model):
@@ -1,11 +1,12 @@
from __future__ import absolute_import, unicode_literals
+from django.db import models
from django.test import TestCase
from django.utils import six
from .models import (Building, Child, Device, Port, Item, Country, Connection,
ClientStatus, State, Client, SpecialClient, TUser, Person, Student,
- Organizer, Class, Enrollment, Hen, Chick)
+ Organizer, Class, Enrollment, Hen, Chick, Parent, ChildA, ChildB)
class SelectRelatedRegressTests(TestCase):
@@ -173,3 +174,20 @@ def test_regression_19870(self):
self.assertEqual(Chick.objects.all()[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.