diff options
| author | Jon Dufresne <jon.dufresne@gmail.com> | 2017-01-31 06:41:51 -0800 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-01-31 09:43:31 -0500 |
| commit | 52e9c1c8b72bc30a66d838187bd9ecb1f22f8448 (patch) | |
| tree | 0a67f6c3b1f85902ef075863a7a0a186d59c7d71 | |
| parent | e2b19e70c7df99b3dc00c174741d01c2977aef00 (diff) | |
[1.11.x] Fixed #27758 -- Reallowed AdvancedModelIterator pattern after template widget rendering.
Backport of 6d8979f4c2fbfb9fd5db92acd72489cbbcbdd5d1 from master
| -rw-r--r-- | django/forms/widgets.py | 4 | ||||
| -rw-r--r-- | tests/model_forms/tests.py | 39 |
2 files changed, 40 insertions, 3 deletions
diff --git a/django/forms/widgets.py b/django/forms/widgets.py index f50ddd52ba..594b578431 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -569,8 +569,6 @@ class ChoiceWidget(Widget): for option_value, option_label in chain(self.choices): if option_value is None: option_value = '' - else: - option_value = force_text(option_value) if isinstance(option_label, (list, tuple)): index = groups[-1][2] + 1 @@ -586,7 +584,7 @@ class ChoiceWidget(Widget): for subvalue, sublabel in choices: selected = ( - subvalue in value and + force_text(subvalue) in value and (has_selected is False or self.allow_multiple_selected) ) if selected is True and has_selected is False: diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 1686629c3a..8b293a02ad 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -17,6 +17,7 @@ from django.forms.models import ( ModelChoiceIterator, ModelFormMetaclass, construct_instance, fields_for_model, model_to_dict, modelform_factory, ) +from django.forms.widgets import CheckboxSelectMultiple from django.template import Context, Template from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature from django.utils import six @@ -1708,6 +1709,44 @@ class ModelChoiceFieldTests(TestCase): field = CustomModelChoiceField(Category.objects.all()) self.assertIsInstance(field.choices, CustomModelChoiceIterator) + def test_modelchoicefield_iterator_pass_model_to_widget(self): + class CustomModelChoiceValue: + def __init__(self, value, obj): + self.value = value + self.obj = obj + + def __str__(self): + return str(self.value) + + class CustomModelChoiceIterator(ModelChoiceIterator): + def choice(self, obj): + value, label = super(CustomModelChoiceIterator, self).choice(obj) + return CustomModelChoiceValue(value, obj), label + + class CustomCheckboxSelectMultiple(CheckboxSelectMultiple): + def create_option(self, name, value, label, selected, index, subindex=None, attrs=None): + option = super(CustomCheckboxSelectMultiple, self).create_option( + name, value, label, selected, index, subindex=None, attrs=None, + ) + # Modify the HTML based on the object being rendered. + c = value.obj + option['attrs']['data-slug'] = c.slug + return option + + class CustomModelMultipleChoiceField(forms.ModelMultipleChoiceField): + iterator = CustomModelChoiceIterator + widget = CustomCheckboxSelectMultiple + + field = CustomModelMultipleChoiceField(Category.objects.all()) + self.assertHTMLEqual( + field.widget.render('name', []), + '''<ul> +<li><label><input type="checkbox" name="name" value="%d" data-slug="entertainment" />Entertainment</label></li> +<li><label><input type="checkbox" name="name" value="%d" data-slug="its-test" />It's a test</label></li> +<li><label><input type="checkbox" name="name" value="%d" data-slug="third-test" />Third</label></li> +</ul>''' % (self.c1.pk, self.c2.pk, self.c3.pk), + ) + def test_modelchoicefield_num_queries(self): """ Widgets that render multiple subwidgets shouldn't make more than one |
