mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #19837 -- Refactored split_exclude() join generation
The refactoring mainly concentrates on making sure the inner and outer
query agree about the split position. The split position is where the
multijoin happens, and thus the split position also determines the
columns used in the "WHERE col1 IN (SELECT col2 from ...)" condition.
This commit fixes a regression caused by #10790 and commit
69597e5bcc. The regression was caused
by wrong cols in the split position.
This commit is contained in:
@@ -24,7 +24,7 @@ from .models import (Annotation, Article, Author, Celebrity, Child, Cover,
|
||||
Node, ObjectA, ObjectB, ObjectC, CategoryItem, SimpleCategory,
|
||||
SpecialCategory, OneToOneCategory, NullableName, ProxyCategory,
|
||||
SingleObject, RelatedObject, ModelA, ModelD, Responsibility, Job,
|
||||
JobResponsibilities, BaseA)
|
||||
JobResponsibilities, BaseA, Identifier, Program, Channel)
|
||||
|
||||
|
||||
class BaseQuerysetTest(TestCase):
|
||||
@@ -2612,3 +2612,22 @@ class DisjunctionPromotionTests(TestCase):
|
||||
qs = BaseA.objects.filter(Q(a__f1=F('c__f1')) | (Q(pk=1) & Q(pk=2)))
|
||||
self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 2)
|
||||
self.assertEqual(str(qs.query).count('INNER JOIN'), 0)
|
||||
|
||||
|
||||
class ManyToManyExcludeTest(TestCase):
|
||||
def test_exclude_many_to_many(self):
|
||||
Identifier.objects.create(name='extra')
|
||||
program = Program.objects.create(identifier=Identifier.objects.create(name='program'))
|
||||
channel = Channel.objects.create(identifier=Identifier.objects.create(name='channel'))
|
||||
channel.programs.add(program)
|
||||
|
||||
# channel contains 'program1', so all Identifiers except that one
|
||||
# should be returned
|
||||
self.assertQuerysetEqual(
|
||||
Identifier.objects.exclude(program__channel=channel).order_by('name'),
|
||||
['<Identifier: channel>', '<Identifier: extra>']
|
||||
)
|
||||
self.assertQuerysetEqual(
|
||||
Identifier.objects.exclude(program__channel=None).order_by('name'),
|
||||
['<Identifier: program>']
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user