Fixed #21787 -- regression in MTI .exclude() queries
This commit is contained in:
parent
16f3a6a4c7
commit
78a2617703
|
@ -1334,6 +1334,7 @@ class Query(object):
|
||||||
"""
|
"""
|
||||||
path, names_with_path = [], []
|
path, names_with_path = [], []
|
||||||
for pos, name in enumerate(names):
|
for pos, name in enumerate(names):
|
||||||
|
cur_names_with_path = (name, [])
|
||||||
if name == 'pk':
|
if name == 'pk':
|
||||||
name = opts.pk.name
|
name = opts.pk.name
|
||||||
try:
|
try:
|
||||||
|
@ -1359,19 +1360,22 @@ class Query(object):
|
||||||
targets = (final_field.rel.get_related_field(),)
|
targets = (final_field.rel.get_related_field(),)
|
||||||
opts = int_model._meta
|
opts = int_model._meta
|
||||||
path.append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
|
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'):
|
if hasattr(field, 'get_path_info'):
|
||||||
pathinfos = field.get_path_info()
|
pathinfos = field.get_path_info()
|
||||||
if not allow_many:
|
if not allow_many:
|
||||||
for inner_pos, p in enumerate(pathinfos):
|
for inner_pos, p in enumerate(pathinfos):
|
||||||
if p.m2m:
|
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)
|
raise MultiJoin(pos + 1, names_with_path)
|
||||||
last = pathinfos[-1]
|
last = pathinfos[-1]
|
||||||
path.extend(pathinfos)
|
path.extend(pathinfos)
|
||||||
final_field = last.join_field
|
final_field = last.join_field
|
||||||
opts = last.to_opts
|
opts = last.to_opts
|
||||||
targets = last.target_fields
|
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:
|
else:
|
||||||
# Local non-relational field.
|
# Local non-relational field.
|
||||||
final_field = field
|
final_field = field
|
||||||
|
|
|
@ -3225,3 +3225,21 @@ class ValuesJoinPromotionTests(TestCase):
|
||||||
self.assertEqual(qs.count(), 1)
|
self.assertEqual(qs.count(), 1)
|
||||||
tblname = connection.ops.quote_name(ObjectB._meta.db_table)
|
tblname = connection.ops.quote_name(ObjectB._meta.db_table)
|
||||||
self.assertTrue(' LEFT OUTER JOIN %s' % tblname in str(qs.query))
|
self.assertTrue(' LEFT OUTER JOIN %s' % tblname in str(qs.query))
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue