From 139135627650ed6aaaf4c755b82c3bd43f2b8f51 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Thu, 12 Jan 2023 19:13:22 +0100 Subject: [PATCH] Refs #29984 -- Made QuerySet.iterator() without chunk_size raise ValueError after prefetch_related(). Per deprecation timeline. --- django/db/models/query.py | 14 +++----------- docs/ref/models/querysets.txt | 6 ------ docs/releases/5.0.txt | 3 +++ tests/prefetch_related/tests.py | 24 +++++------------------- 4 files changed, 11 insertions(+), 36 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index c943cfe2193..f88662de12e 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -33,7 +33,6 @@ from django.db.models.utils import ( resolve_callables, ) from django.utils import timezone -from django.utils.deprecation import RemovedInDjango50Warning from django.utils.functional import cached_property, partition # The maximum number of results to fetch in a get() query. @@ -529,16 +528,9 @@ class QuerySet(AltersData): """ if chunk_size is None: if self._prefetch_related_lookups: - # When the deprecation ends, replace with: - # raise ValueError( - # 'chunk_size must be provided when using ' - # 'QuerySet.iterator() after prefetch_related().' - # ) - warnings.warn( - "Using QuerySet.iterator() after prefetch_related() " - "without specifying chunk_size is deprecated.", - category=RemovedInDjango50Warning, - stacklevel=2, + raise ValueError( + "chunk_size must be provided when using QuerySet.iterator() after " + "prefetch_related()." ) elif chunk_size <= 0: raise ValueError("Chunk size must be strictly positive.") diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 4a1836ba14e..df77cabe33c 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -2476,12 +2476,6 @@ value for ``chunk_size`` will result in Django using an implicit default of Depending on the database backend, query results will either be loaded all at once or streamed from the database using server-side cursors. -.. deprecated:: 4.1 - - Using ``iterator()`` on a queryset that prefetches related objects without - providing the ``chunk_size`` is deprecated. In Django 5.0, an exception - will be raise. - With server-side cursors ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt index d39b8d314a3..e058f4a76c7 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -319,3 +319,6 @@ to remove usage of these features. ``SimpleTestCase.assertFormError()`` and ``assertFormsetError()`` is removed. * ``django.contrib.sessions.serializers.PickleSerializer`` is removed. + +* The usage of ``QuerySet.iterator()`` on a queryset that prefetches related + objects without providing the ``chunk_size`` argument is no longer allowed. diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index c153c0d9ec9..c8b9a9538b0 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -12,8 +12,7 @@ from django.test import ( skipIfDBFeature, skipUnlessDBFeature, ) -from django.test.utils import CaptureQueriesContext, ignore_warnings -from django.utils.deprecation import RemovedInDjango50Warning +from django.test.utils import CaptureQueriesContext from .models import ( Article, @@ -385,25 +384,12 @@ class PrefetchRelatedTests(TestDataMixin, TestCase): [self.author1, self.author1, self.author3, self.author4], ) - @ignore_warnings(category=RemovedInDjango50Warning) - def test_m2m_prefetching_iterator_without_chunks(self): - # prefetch_related() is ignored. - with self.assertNumQueries(5): - authors = [ - b.authors.first() - for b in Book.objects.prefetch_related("authors").iterator() - ] - self.assertEqual( - authors, - [self.author1, self.author1, self.author3, self.author4], - ) - - def test_m2m_prefetching_iterator_without_chunks_warning(self): + def test_m2m_prefetching_iterator_without_chunks_error(self): msg = ( - "Using QuerySet.iterator() after prefetch_related() without " - "specifying chunk_size is deprecated." + "chunk_size must be provided when using QuerySet.iterator() after " + "prefetch_related()." ) - with self.assertWarnsMessage(RemovedInDjango50Warning, msg): + with self.assertRaisesMessage(ValueError, msg): Book.objects.prefetch_related("authors").iterator()