Commit e47b90e4 authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
Browse files

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

Backpatch of 78a26177 from master.
parent c91e772b
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1256,6 +1256,7 @@ class Query(object):
        """
        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 @@ class Query(object):
                        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
+18 −0
Original line number Diff line number Diff line
@@ -3008,3 +3008,21 @@ class Ticket21203Tests(TestCase):
        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
        )