Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.6.x] Fixed #20955 -- select_related regression

In cases where the same connection (from model A to model B along the
same field) was needed multiple times in a select_related query, the
join setup code mistakenly reused an existing join.

Backpatch of 8d65b60.

Conflicts:

	django/db/models/sql/compiler.py
	tests/queries/tests.py
  • Loading branch information...
commit 161e26c2ec9f88bf0395941aaa2fd193b110affd 1 parent 69a4594
Anssi Kääriäinen authored August 22, 2013
5  django/db/models/sql/compiler.py
@@ -687,9 +687,8 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
687 687
                 # Use True here because we are looking at the _reverse_ side of
688 688
                 # the relation, which is always nullable.
689 689
                 new_nullable = True
690  
-                table = model._meta.db_table
691  
-                self.fill_related_selections(model._meta, table, cur_depth+1,
692  
-                    next, restricted, new_nullable)
  690
+                self.fill_related_selections(model._meta, alias, cur_depth + 1,
  691
+                                             next, restricted, new_nullable)
693 692
 
694 693
     def deferred_to_columns(self):
695 694
         """
26  tests/queries/models.py
@@ -497,3 +497,29 @@ class Meta:
497 497
 
498 498
     def __str__(self):
499 499
         return '%s' % self.pk
  500
+
  501
+class BaseUser(models.Model):
  502
+    pass
  503
+
  504
+@python_2_unicode_compatible
  505
+class Task(models.Model):
  506
+    title = models.CharField(max_length=10)
  507
+    owner = models.ForeignKey(BaseUser, related_name='owner')
  508
+    creator = models.ForeignKey(BaseUser, related_name='creator')
  509
+
  510
+    def __str__(self):
  511
+        return self.title
  512
+
  513
+@python_2_unicode_compatible
  514
+class Staff(models.Model):
  515
+    name = models.CharField(max_length=10)
  516
+
  517
+    def __str__(self):
  518
+        return self.name
  519
+
  520
+@python_2_unicode_compatible
  521
+class StaffUser(BaseUser):
  522
+    staff = models.OneToOneField(Staff, related_name='user')
  523
+
  524
+    def __str__(self):
  525
+        return self.staff
22  tests/queries/tests.py
@@ -25,7 +25,7 @@
25 25
     OneToOneCategory, NullableName, ProxyCategory, SingleObject, RelatedObject,
26 26
     ModelA, ModelB, ModelC, ModelD, Responsibility, Job, JobResponsibilities,
27 27
     BaseA, FK1, Identifier, Program, Channel, Page, Paragraph, Chapter, Book,
28  
-    MyObject, Order, OrderItem)
  28
+    MyObject, Order, OrderItem, Task, Staff, StaffUser)
29 29
 
30 30
 
31 31
 class BaseQuerysetTest(TestCase):
@@ -2943,3 +2943,23 @@ def test_wrong_type_lookup(self):
2943 2943
         self.assertQuerysetEqual(
2944 2944
             ObjectB.objects.filter(objecta__in=[wrong_type]),
2945 2945
             [ob], lambda x: x)
  2946
+
  2947
+class Ticket20955Tests(TestCase):
  2948
+    def test_ticket_20955(self):
  2949
+        jack = Staff.objects.create(name='jackstaff')
  2950
+        jackstaff = StaffUser.objects.create(staff=jack)
  2951
+        jill = Staff.objects.create(name='jillstaff')
  2952
+        jillstaff = StaffUser.objects.create(staff=jill)
  2953
+        task = Task.objects.create(creator=jackstaff, owner=jillstaff, title="task")
  2954
+        task_get = Task.objects.get(pk=task.pk)
  2955
+        # Load data so that assertNumQueries doesn't complain about the get
  2956
+        # version's queries.
  2957
+        task_get.creator.staffuser.staff
  2958
+        task_get.owner.staffuser.staff
  2959
+        task_select_related = Task.objects.select_related(
  2960
+            'creator__staffuser__staff', 'owner__staffuser__staff').get(pk=task.pk)
  2961
+        with self.assertNumQueries(0):
  2962
+            self.assertEqual(task_select_related.creator.staffuser.staff,
  2963
+                             task_get.creator.staffuser.staff)
  2964
+            self.assertEqual(task_select_related.owner.staffuser.staff,
  2965
+                             task_get.owner.staffuser.staff)

0 notes on commit 161e26c

Please sign in to comment.
Something went wrong with that request. Please try again.