summaryrefslogtreecommitdiff
path: root/tests/prefetch_related
diff options
context:
space:
mode:
authorAlex Aktsipetrov <aaktsipetrov@iponweb.net>2019-10-15 01:59:43 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-10-21 13:21:54 +0200
commit681f7e2b13846def9eff3d26ce1371d05fa90c4c (patch)
treec879edafb74a7e39dd53186a5cfd9b0996d522f9 /tests/prefetch_related
parent70d81469861f0abe8e7cb325f743b85f28d03b71 (diff)
downloaddjango-681f7e2b13846def9eff3d26ce1371d05fa90c4c.tar.gz
Fixed #20577 -- Deferred filtering of prefetched related querysets.
Added internal interface to QuerySet that allows to defer next filter call till .query is accessed. Used it to optimize prefetch_related(). Thanks Simon Charette for the review.
Diffstat (limited to 'tests/prefetch_related')
-rw-r--r--tests/prefetch_related/tests.py31
1 files changed, 31 insertions, 0 deletions
diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py
index 930ba9fbc8..5b944a456b 100644
--- a/tests/prefetch_related/tests.py
+++ b/tests/prefetch_related/tests.py
@@ -5,6 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db import connection
from django.db.models import Prefetch, QuerySet
from django.db.models.query import get_prefetcher, prefetch_related_objects
+from django.db.models.sql import Query
from django.test import TestCase, override_settings
from django.test.utils import CaptureQueriesContext
@@ -291,6 +292,20 @@ class PrefetchRelatedTests(TestDataMixin, TestCase):
sql = queries[-1]['sql']
self.assertWhereContains(sql, self.author1.id)
+ def test_filter_deferred(self):
+ """
+ Related filtering of prefetched querysets is deferred until necessary.
+ """
+ add_q = Query.add_q
+ with mock.patch.object(
+ Query,
+ 'add_q',
+ autospec=True,
+ side_effect=lambda self, q: add_q(self, q),
+ ) as add_q_mock:
+ list(Book.objects.prefetch_related('authors'))
+ self.assertEqual(add_q_mock.call_count, 1)
+
class RawQuerySetTests(TestDataMixin, TestCase):
def test_basic(self):
@@ -823,6 +838,22 @@ class CustomPrefetchTests(TestCase):
with self.assertNumQueries(0):
self.assertEqual(person.cached_all_houses, all_houses)
+ def test_filter_deferred(self):
+ """
+ Related filtering of prefetched querysets is deferred until necessary.
+ """
+ add_q = Query.add_q
+ with mock.patch.object(
+ Query,
+ 'add_q',
+ autospec=True,
+ side_effect=lambda self, q: add_q(self, q),
+ ) as add_q_mock:
+ list(House.objects.prefetch_related(
+ Prefetch('occupants', queryset=Person.objects.all())
+ ))
+ self.assertEqual(add_q_mock.call_count, 1)
+
class DefaultManagerTests(TestCase):