Fixed #27758 -- Reallowed AdvancedModelIterator pattern after template widget rendering.
This commit is contained in:
parent
3b2e28fc85
commit
6d8979f4c2
|
@ -552,8 +552,6 @@ class ChoiceWidget(Widget):
|
||||||
for option_value, option_label in chain(self.choices):
|
for option_value, option_label in chain(self.choices):
|
||||||
if option_value is None:
|
if option_value is None:
|
||||||
option_value = ''
|
option_value = ''
|
||||||
else:
|
|
||||||
option_value = force_text(option_value)
|
|
||||||
|
|
||||||
if isinstance(option_label, (list, tuple)):
|
if isinstance(option_label, (list, tuple)):
|
||||||
index = groups[-1][2] + 1
|
index = groups[-1][2] + 1
|
||||||
|
@ -569,7 +567,7 @@ class ChoiceWidget(Widget):
|
||||||
|
|
||||||
for subvalue, sublabel in choices:
|
for subvalue, sublabel in choices:
|
||||||
selected = (
|
selected = (
|
||||||
subvalue in value and
|
force_text(subvalue) in value and
|
||||||
(has_selected is False or self.allow_multiple_selected)
|
(has_selected is False or self.allow_multiple_selected)
|
||||||
)
|
)
|
||||||
if selected is True and has_selected is False:
|
if selected is True and has_selected is False:
|
||||||
|
|
|
@ -15,6 +15,7 @@ from django.forms.models import (
|
||||||
ModelChoiceIterator, ModelFormMetaclass, construct_instance,
|
ModelChoiceIterator, ModelFormMetaclass, construct_instance,
|
||||||
fields_for_model, model_to_dict, modelform_factory,
|
fields_for_model, model_to_dict, modelform_factory,
|
||||||
)
|
)
|
||||||
|
from django.forms.widgets import CheckboxSelectMultiple
|
||||||
from django.template import Context, Template
|
from django.template import Context, Template
|
||||||
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
|
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
|
||||||
|
|
||||||
|
@ -1704,6 +1705,42 @@ class ModelChoiceFieldTests(TestCase):
|
||||||
field = CustomModelChoiceField(Category.objects.all())
|
field = CustomModelChoiceField(Category.objects.all())
|
||||||
self.assertIsInstance(field.choices, CustomModelChoiceIterator)
|
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().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().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):
|
def test_modelchoicefield_num_queries(self):
|
||||||
"""
|
"""
|
||||||
Widgets that render multiple subwidgets shouldn't make more than one
|
Widgets that render multiple subwidgets shouldn't make more than one
|
||||||
|
|
Loading…
Reference in New Issue