mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #19500 -- Solved a regression in join reuse
The ORM didn't reuse joins for direct foreign key traversals when using
chained filters. For example:
qs.filter(fk__somefield=1).filter(fk__somefield=2))
produced two joins.
As a bonus, reverse onetoone filters can now reuse joins correctly
The regression was caused by the join() method refactor in commit
68847135bc
Thanks for Simon Charette for spotting some issues with the first draft
of the patch.
This commit is contained in:
@@ -2418,3 +2418,36 @@ class ReverseJoinTrimmingTest(TestCase):
|
||||
qs = Tag.objects.filter(annotation__tag=t.pk)
|
||||
self.assertIn('INNER JOIN', str(qs.query))
|
||||
self.assertEquals(list(qs), [])
|
||||
|
||||
class JoinReuseTest(TestCase):
|
||||
"""
|
||||
Test that the queries reuse joins sensibly (for example, direct joins
|
||||
are always reused).
|
||||
"""
|
||||
def test_fk_reuse(self):
|
||||
qs = Annotation.objects.filter(tag__name='foo').filter(tag__name='bar')
|
||||
self.assertEqual(str(qs.query).count('JOIN'), 1)
|
||||
|
||||
def test_fk_reuse_select_related(self):
|
||||
qs = Annotation.objects.filter(tag__name='foo').select_related('tag')
|
||||
self.assertEqual(str(qs.query).count('JOIN'), 1)
|
||||
|
||||
def test_fk_reuse_annotation(self):
|
||||
qs = Annotation.objects.filter(tag__name='foo').annotate(cnt=Count('tag__name'))
|
||||
self.assertEqual(str(qs.query).count('JOIN'), 1)
|
||||
|
||||
def test_fk_reuse_disjunction(self):
|
||||
qs = Annotation.objects.filter(Q(tag__name='foo') | Q(tag__name='bar'))
|
||||
self.assertEqual(str(qs.query).count('JOIN'), 1)
|
||||
|
||||
def test_fk_reuse_order_by(self):
|
||||
qs = Annotation.objects.filter(tag__name='foo').order_by('tag__name')
|
||||
self.assertEqual(str(qs.query).count('JOIN'), 1)
|
||||
|
||||
def test_revo2o_reuse(self):
|
||||
qs = Detail.objects.filter(member__name='foo').filter(member__name='foo')
|
||||
self.assertEqual(str(qs.query).count('JOIN'), 1)
|
||||
|
||||
def test_revfk_noreuse(self):
|
||||
qs = Author.objects.filter(report__name='r4').filter(report__name='r1')
|
||||
self.assertEqual(str(qs.query).count('JOIN'), 2)
|
||||
|
||||
Reference in New Issue
Block a user