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 #21787 -- regression in MTI .exclude() queries

Backpatch of 78a2617 from master.
  • Loading branch information...
commit e47b90e48f3532d312afcfaec55b2711b2129c02 1 parent c91e772
Anssi Kääriäinen authored January 20, 2014
8  django/db/models/sql/query.py
@@ -1256,6 +1256,7 @@ def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
1256 1256
         """
1257 1257
         path, names_with_path = [], []
1258 1258
         for pos, name in enumerate(names):
  1259
+            cur_names_with_path = (name, [])
1259 1260
             if name == 'pk':
1260 1261
                 name = opts.pk.name
1261 1262
             try:
@@ -1288,19 +1289,22 @@ def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
1288 1289
                         targets = (final_field.rel.get_related_field(),)
1289 1290
                         opts = int_model._meta
1290 1291
                         path.append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
  1292
+                        cur_names_with_path[1].append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
1291 1293
             if hasattr(field, 'get_path_info'):
1292 1294
                 pathinfos = field.get_path_info()
1293 1295
                 if not allow_many:
1294 1296
                     for inner_pos, p in enumerate(pathinfos):
1295 1297
                         if p.m2m:
1296  
-                            names_with_path.append((name, pathinfos[0:inner_pos + 1]))
  1298
+                            cur_names_with_path[1].extend(pathinfos[0:inner_pos + 1])
  1299
+                            names_with_path.append(cur_names_with_path)
1297 1300
                             raise MultiJoin(pos + 1, names_with_path)
1298 1301
                 last = pathinfos[-1]
1299 1302
                 path.extend(pathinfos)
1300 1303
                 final_field = last.join_field
1301 1304
                 opts = last.to_opts
1302 1305
                 targets = last.target_fields
1303  
-                names_with_path.append((name, pathinfos))
  1306
+                cur_names_with_path[1].extend(pathinfos)
  1307
+                names_with_path.append(cur_names_with_path)
1304 1308
             else:
1305 1309
                 # Local non-relational field.
1306 1310
                 final_field = field
18  tests/queries/tests.py
@@ -3008,3 +3008,21 @@ def test_ticket_21203(self):
3008 3008
         qs = Ticket21203Child.objects.select_related('parent').defer('parent__created')
3009 3009
         self.assertQuerysetEqual(qs, [c], lambda x: x)
3010 3010
         self.assertIs(qs[0].parent.parent_bool, True)
  3011
+
  3012
+
  3013
+class ForeignKeyToBaseExcludeTests(TestCase):
  3014
+    def test_ticket_21787(self):
  3015
+        sc1 = SpecialCategory.objects.create(special_name='sc1', name='sc1')
  3016
+        sc2 = SpecialCategory.objects.create(special_name='sc2', name='sc2')
  3017
+        sc3 = SpecialCategory.objects.create(special_name='sc3', name='sc3')
  3018
+        c1 = CategoryItem.objects.create(category=sc1)
  3019
+        CategoryItem.objects.create(category=sc2)
  3020
+        self.assertQuerysetEqual(
  3021
+            SpecialCategory.objects.exclude(
  3022
+                categoryitem__id=c1.pk).order_by('name'),
  3023
+            [sc2, sc3], lambda x: x
  3024
+        )
  3025
+        self.assertQuerysetEqual(
  3026
+            SpecialCategory.objects.filter(categoryitem__id=c1.pk),
  3027
+            [sc1], lambda x: x
  3028
+        )

0 notes on commit e47b90e

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