diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 7ba94f205b..387b91a60b 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -8,7 +8,7 @@ all about the internals of models in order to get the information it needs. """ import copy import warnings -from collections import Mapping, OrderedDict +from collections import Iterator, Mapping, OrderedDict from itertools import chain, count, product from string import ascii_uppercase @@ -1167,6 +1167,9 @@ class Query(object): field, sources, opts, join_list, path = self.setup_joins( parts, opts, alias, can_reuse=can_reuse, allow_many=allow_many) + # Prevent iterator from being consumed by check_related_objects() + if isinstance(value, Iterator): + value = list(value) self.check_related_objects(field, value, opts) # split_exclude() needs to know which joins were generated for the diff --git a/docs/releases/1.8.1.txt b/docs/releases/1.8.1.txt index 9593c13551..d2b16d62da 100644 --- a/docs/releases/1.8.1.txt +++ b/docs/releases/1.8.1.txt @@ -69,6 +69,9 @@ Bugfixes * Fixed a migration crash when applying migrations with model managers on Python 3 that were generated on Python 2 (:ticket:`24701`). +* Restored the ability to use iterators as queryset filter arguments + (:ticket:`24719`). + Optimizations ============= diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 5d12330b99..2a62c8db90 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -3520,6 +3520,7 @@ class RelatedLookupTypeTests(TestCase): # child objects self.assertQuerysetEqual(ObjectB.objects.filter(objecta__in=[self.coa]), []) self.assertQuerysetEqual(ObjectB.objects.filter(objecta__in=[self.poa, self.coa]).order_by('name'), out_b) + self.assertQuerysetEqual(ObjectB.objects.filter(objecta__in=iter([self.poa, self.coa])).order_by('name'), out_b) # parent objects self.assertQuerysetEqual(ObjectC.objects.exclude(childobjecta=self.oa), out_c)