diff options
author | Alex Aktsipetrov <aaktsipetrov@iponweb.net> | 2019-10-15 01:59:43 +0300 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-10-21 13:21:54 +0200 |
commit | 681f7e2b13846def9eff3d26ce1371d05fa90c4c (patch) | |
tree | c879edafb74a7e39dd53186a5cfd9b0996d522f9 /tests/prefetch_related | |
parent | 70d81469861f0abe8e7cb325f743b85f28d03b71 (diff) | |
download | django-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.py | 31 |
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): |