Loading django/db/models/sql/query.py +6 −2 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 Loading tests/queries/tests.py +18 −0 Original line number Diff line number Diff line Loading @@ -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 ) Loading
django/db/models/sql/query.py +6 −2 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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 Loading
tests/queries/tests.py +18 −0 Original line number Diff line number Diff line Loading @@ -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 )