diff --git a/django/db/models/query.py b/django/db/models/query.py index 41c24c7a583..08fda783320 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -485,7 +485,7 @@ class QuerySet(object): qs = self._clone() qs.query.add_filter(('pk__in', id_list)) qs.query.clear_ordering(force_empty=True) - return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()]) + return dict([(obj._get_pk_val(), obj) for obj in qs]) def delete(self): """ diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 4d6b9bc533f..13504f41cf0 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -871,6 +871,9 @@ could be generated, which, depending on the database, might have performance problems of its own when it comes to parsing or executing the SQL query. Always profile for your use case! +Note that if you use ``iterator()`` to run the query, ``prefetch_related()`` +calls will be ignored since these two optimizations do not make sense together. + extra ~~~~~ @@ -1430,6 +1433,9 @@ performance and a significant reduction in memory. Note that using ``iterator()`` on a ``QuerySet`` which has already been evaluated will force it to evaluate again, repeating the query. +Also, use of ``iterator()`` causes previous ``prefetch_related()`` calls to be +ignored since these two optimizations do not make sense together. + latest ~~~~~~ diff --git a/tests/modeltests/prefetch_related/tests.py b/tests/modeltests/prefetch_related/tests.py index 4c51a83bd96..382aed68b45 100644 --- a/tests/modeltests/prefetch_related/tests.py +++ b/tests/modeltests/prefetch_related/tests.py @@ -470,3 +470,16 @@ class NullableTest(TestCase): for e in qs2] self.assertEqual(co_serfs, co_serfs2) + + def test_in_bulk(self): + """ + In-bulk does correctly prefetch objects by not using .iterator() + directly. + """ + boss1 = Employee.objects.create(name="Peter") + boss2 = Employee.objects.create(name="Jack") + with self.assertNumQueries(2): + # Check that prefetch is done and it does not cause any errors. + bulk = Employee.objects.prefetch_related('serfs').in_bulk([boss1.pk, boss2.pk]) + for b in bulk.values(): + list(b.serfs.all())