[1.8.x] Fixed #25683 -- Allowed ModelChoiceField(queryset=...) to accept Managers.

This fixes a regression from refs #25496.

Backport of 1155843a41 from master
This commit is contained in:
Marti Raudsepp 2015-11-05 19:02:18 +02:00 committed by Tim Graham
parent a42c5376e7
commit 3144785ebf
3 changed files with 20 additions and 8 deletions

View File

@ -1092,17 +1092,19 @@ class ModelChoiceIterator(object):
def __iter__(self): def __iter__(self):
if self.field.empty_label is not None: if self.field.empty_label is not None:
yield ("", self.field.empty_label) yield ("", self.field.empty_label)
method = 'all' if self.queryset._prefetch_related_lookups else 'iterator' queryset = self.queryset.all()
queryset = getattr(self.queryset, method) # Can't use iterator() when queryset uses prefetch_related()
if not queryset._prefetch_related_lookups:
queryset = queryset.iterator()
if self.field.cache_choices: if self.field.cache_choices:
if self.field.choice_cache is None: if self.field.choice_cache is None:
self.field.choice_cache = [ self.field.choice_cache = [
self.choice(obj) for obj in queryset() self.choice(obj) for obj in queryset
] ]
for choice in self.field.choice_cache: for choice in self.field.choice_cache:
yield choice yield choice
else: else:
for obj in queryset(): for obj in queryset:
yield self.choice(obj) yield self.choice(obj)
def __len__(self): def __len__(self):

View File

@ -14,3 +14,7 @@ Bugfixes
* Fixed a regression in 1.8.6 that caused database routers without an * Fixed a regression in 1.8.6 that caused database routers without an
``allow_migrate()`` method to crash (:ticket:`25686`). ``allow_migrate()`` method to crash (:ticket:`25686`).
* Fixed a regression in 1.8.6 by restoring the ability to use ``Manager``
objects for the ``queryset`` argument of ``ModelChoiceField``
(:ticket:`25683`).

View File

@ -60,17 +60,23 @@ class FileForm(Form):
file1 = FileField() file1 = FileField()
class TestTicket12510(TestCase): class TestModelChoiceField(TestCase):
''' It is not necessary to generate choices for ModelChoiceField (regression test for #12510). '''
def setUp(self):
self.groups = [Group.objects.create(name=name) for name in 'abc']
def test_choices_not_fetched_when_not_rendering(self): def test_choices_not_fetched_when_not_rendering(self):
"""
Generating choices for ModelChoiceField should require 1 query (#12510).
"""
self.groups = [Group.objects.create(name=name) for name in 'abc']
# only one query is required to pull the model from DB # only one query is required to pull the model from DB
with self.assertNumQueries(1): with self.assertNumQueries(1):
field = ModelChoiceField(Group.objects.order_by('-name')) field = ModelChoiceField(Group.objects.order_by('-name'))
self.assertEqual('a', field.clean(self.groups[0].pk).name) self.assertEqual('a', field.clean(self.groups[0].pk).name)
def test_queryset_manager(self):
f = ModelChoiceField(ChoiceOptionModel.objects)
choice = ChoiceOptionModel.objects.create(name="choice 1")
self.assertEqual(list(f.choices), [('', '---------'), (choice.pk, str(choice))])
class TestTicket14567(TestCase): class TestTicket14567(TestCase):
""" """