Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: django/django
head fork: akaariai/django
compare: ticket_20528
Checking mergeability… Don't worry, you can still create the pull request.
  • 3 commits
  • 4 files changed
  • 0 commit comments
  • 2 contributors
9 django/db/models/sql/
@@ -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.
@@ -1913,5 +1913,8 @@ def alias_diff(refcounts_before, refcounts_after):
Given the before and after copies of refcounts works out which aliases
have been added to the after copy.
+ # The "t not in refcounts_before" condition is needed for cases where
+ # a join is created but then trimmed.
return set(t for t in refcounts_after
- if refcounts_after[t] > refcounts_before.get(t, 0))
+ if refcounts_after[t] > refcounts_before.get(t, 0)
+ or t not in refcounts_before)
4 docs/ref/contrib/flatpages.txt
@@ -47,7 +47,7 @@ Then either:
3. Add an entry in your URLconf. For example::
urlpatterns = patterns('',
- ('^pages/', include('django.contrib.flatpages.urls')),
+ (r'^pages/', include('django.contrib.flatpages.urls')),
@@ -74,7 +74,7 @@ There are several ways to include the flat pages in your URLconf. You can
dedicate a particular path to flat pages::
urlpatterns = patterns('',
- ('^pages/', include('django.contrib.flatpages.urls')),
+ (r'^pages/', include('django.contrib.flatpages.urls')),
You can also set it up as a "catchall" pattern. In this case, it is important
12 tests/select_related_regress/
@@ -95,6 +95,18 @@ class Item(models.Model):
def __str__(self):
+class ChildA(models.Model):
+ parent = models.ForeignKey(Parent)
+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
# Models for testing bug #19870.
class Fowl(models.Model):
20 tests/select_related_regress/
@@ -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], 'Hen')
self.assertEqual(Chick.objects.select_related()[0], '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)

No commit comments for this range

Something went wrong with that request. Please try again.