Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[1.6.x] Fixed #21787 -- regression in MTI .exclude() queries

Backpatch of 78a2617 from master.
  • Loading branch information...
commit e47b90e48f3532d312afcfaec55b2711b2129c02 1 parent c91e772
@akaariai akaariai authored
Showing with 24 additions and 2 deletions.
  1. +6 −2 django/db/models/sql/query.py
  2. +18 −0 tests/queries/tests.py
View
8 django/db/models/sql/query.py
@@ -1256,6 +1256,7 @@ def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
"""
path, names_with_path = [], []
for pos, name in enumerate(names):
+ cur_names_with_path = (name, [])
if name == 'pk':
name = opts.pk.name
try:
@@ -1288,19 +1289,22 @@ def names_to_path(self, names, opts, allow_many, allow_explicit_fk):
targets = (final_field.rel.get_related_field(),)
opts = int_model._meta
path.append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
+ cur_names_with_path[1].append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
if hasattr(field, 'get_path_info'):
pathinfos = field.get_path_info()
if not allow_many:
for inner_pos, p in enumerate(pathinfos):
if p.m2m:
- names_with_path.append((name, pathinfos[0:inner_pos + 1]))
+ cur_names_with_path[1].extend(pathinfos[0:inner_pos + 1])
+ names_with_path.append(cur_names_with_path)
raise MultiJoin(pos + 1, names_with_path)
last = pathinfos[-1]
path.extend(pathinfos)
final_field = last.join_field
opts = last.to_opts
targets = last.target_fields
- names_with_path.append((name, pathinfos))
+ cur_names_with_path[1].extend(pathinfos)
+ names_with_path.append(cur_names_with_path)
else:
# Local non-relational field.
final_field = field
View
18 tests/queries/tests.py
@@ -3008,3 +3008,21 @@ def test_ticket_21203(self):
qs = Ticket21203Child.objects.select_related('parent').defer('parent__created')
self.assertQuerysetEqual(qs, [c], lambda x: x)
self.assertIs(qs[0].parent.parent_bool, True)
+
+
+class ForeignKeyToBaseExcludeTests(TestCase):
+ def test_ticket_21787(self):
+ sc1 = SpecialCategory.objects.create(special_name='sc1', name='sc1')
+ sc2 = SpecialCategory.objects.create(special_name='sc2', name='sc2')
+ sc3 = SpecialCategory.objects.create(special_name='sc3', name='sc3')
+ c1 = CategoryItem.objects.create(category=sc1)
+ CategoryItem.objects.create(category=sc2)
+ self.assertQuerysetEqual(
+ SpecialCategory.objects.exclude(
+ categoryitem__id=c1.pk).order_by('name'),
+ [sc2, sc3], lambda x: x
+ )
+ self.assertQuerysetEqual(
+ SpecialCategory.objects.filter(categoryitem__id=c1.pk),
+ [sc1], lambda x: x
+ )
Please sign in to comment.
Something went wrong with that request. Please try again.