It seems very few people used it, but... I did. Here you can read:
Some undocumented classes in django.forms.widgets are removed: SubWidget RendererMixin, ChoiceFieldRenderer, RadioFieldRenderer, CheckboxFieldRenderer ChoiceInput, RadioChoiceInput, CheckboxChoiceInput
My source code is:
from django.forms.widgets import ChoiceFieldRenderer, RadioChoiceInput, \
RendererMixin, Select
class BootstrapRadioFieldRenderer(ChoiceFieldRenderer):
outer_html = '<span {id_attr}>{content}</span>'
inner_html = '<div class="radio">{choice_value}{sub_widgets}</div>'
choice_input_class = RadioChoiceInput
class BootstrapRadioSelect(RendererMixin, Select):
renderer = BootstrapRadioFieldRenderer
_empty_value = ''
I really dont know how to convert this to make it work with 1.11 and later: they say:
Use a custom widget template instead.
Well. How?
We used RadioFieldRenderer to add a description to each option. Your usecase may be far from it, but I hope it helps you to make the migration too.
This was the legacy code for Django <=1.10
class MyRadioFieldRenderer(forms.widgets.RadioFieldRenderer):
def render(self):
radios = []
for w in self:
radios.append(u"""<li class="%s">%s <span>%s</span></li>"""
% (w.choice_value, force_unicode(w), get_description(w)))
return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join(radios))
class MyRadioSelect(forms.RadioSelect):
renderer = MyRadioFieldRenderer
And I replaced it with this for Django 1.11 utilizing custom template snippets and only adding the description to the template context.
from django.forms.widgets import RadioSelect
class MyRadioSelect(RadioSelect):
template_name = 'myapp/multiple_input.html'
option_template_name = 'myapp/input_option.html'
def get_context(self, name, value, attrs):
context = super(MyRadioSelect, self).get_context(name, value, attrs)
for i in range(len(context['widget']['optgroups'][0][1])):
value = context['widget']['optgroups'][0][1][i]['value']
context['widget']['optgroups'][0][1][i]['attrs']['description'] = \
get_description(value)
return context
The for loop in this deep list is not pretty. Need to look at that again.
In the template snippet I can then render the description behind the options with <span>{{widget.attrs.description | safe}}</span>
The form remained the same:
class MyForm(forms.Form):
order_method = ChoiceField(
widget=MyRadioSelect,
required=True)
Important: For Django to find your custom template snippets in the regular template folder add this to your settings:
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
and django.forms
to your INSTALLED_APPS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With