1
0
mirror of https://github.com/django/django.git synced 2025-10-23 21:59:11 +00:00

Fixed #29984 -- Added QuerySet.iterator() support for prefetching related objects.

Co-authored-by: Raphael Kimmig <raphael.kimmig@ampad.de>
Co-authored-by: Simon Charette <charette.s@gmail.com>
This commit is contained in:
Jacob Walls
2022-01-09 00:58:41 -05:00
committed by Mariusz Felisiak
parent c27932ec93
commit edbf930287
5 changed files with 112 additions and 13 deletions

View File

@@ -7,7 +7,8 @@ from django.db.models import Prefetch, QuerySet, prefetch_related_objects
from django.db.models.query import get_prefetcher
from django.db.models.sql import Query
from django.test import TestCase, override_settings
from django.test.utils import CaptureQueriesContext
from django.test.utils import CaptureQueriesContext, ignore_warnings
from django.utils.deprecation import RemovedInDjango50Warning
from .models import (
Article, Author, Author2, AuthorAddress, AuthorWithAge, Bio, Book,
@@ -316,6 +317,38 @@ class PrefetchRelatedTests(TestDataMixin, TestCase):
['Anne', 'Charlotte', 'Emily', 'Jane'],
)
def test_m2m_prefetching_iterator_with_chunks(self):
with self.assertNumQueries(3):
authors = [
b.authors.first()
for b in Book.objects.prefetch_related('authors').iterator(chunk_size=2)
]
self.assertEqual(
authors,
[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):
msg = (
'Using QuerySet.iterator() after prefetch_related() without '
'specifying chunk_size is deprecated.'
)
with self.assertWarnsMessage(RemovedInDjango50Warning, msg):
Book.objects.prefetch_related('authors').iterator()
class RawQuerySetTests(TestDataMixin, TestCase):
def test_basic(self):