Commit 5ec64f96 authored by David Sanders's avatar David Sanders Committed by Tim Graham
Browse files

Fixed #26734 -- Made iterator class configurable on ModelChoiceField.

parent ae2a7da8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1128,6 +1128,7 @@ class ModelChoiceField(ChoiceField):
        'invalid_choice': _('Select a valid choice. That choice is not one of'
                            ' the available choices.'),
    }
    iterator = ModelChoiceIterator

    def __init__(self, queryset, empty_label="---------",
                 required=True, widget=None, label=None, initial=None,
@@ -1195,7 +1196,7 @@ class ModelChoiceField(ChoiceField):
        # accessed) so that we can ensure the QuerySet has not been consumed. This
        # construct might look complicated but it allows for lazy evaluation of
        # the queryset.
        return ModelChoiceIterator(self)
        return self.iterator(self)

    choices = property(_get_choices, ChoiceField._set_choices)

+19 −2
Original line number Diff line number Diff line
@@ -14,8 +14,8 @@ from django.core.validators import ValidationError
from django.db import connection, models
from django.db.models.query import EmptyQuerySet
from django.forms.models import (
    ModelFormMetaclass, construct_instance, fields_for_model, model_to_dict,
    modelform_factory,
    ModelChoiceIterator, ModelFormMetaclass, construct_instance,
    fields_for_model, model_to_dict, modelform_factory,
)
from django.template import Context, Template
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
@@ -1573,6 +1573,23 @@ class ModelChoiceFieldTests(TestCase):
        with self.assertNumQueries(1):
            template.render(Context({'field': field}))

    def test_modelchoicefield_iterator(self):
        """
        Iterator defaults to ModelChoiceIterator and can be overridden with
        the iterator attribute on a ModelChoiceField subclass.
        """
        field = forms.ModelChoiceField(Category.objects.all())
        self.assertIsInstance(field.choices, ModelChoiceIterator)

        class CustomModelChoiceIterator(ModelChoiceIterator):
            pass

        class CustomModelChoiceField(forms.ModelChoiceField):
            iterator = CustomModelChoiceIterator

        field = CustomModelChoiceField(Category.objects.all())
        self.assertIsInstance(field.choices, CustomModelChoiceIterator)


class ModelMultipleChoiceFieldTests(TestCase):
    def setUp(self):