I have several ModelForm
s used to build surveys, whose models contain lots of questions (>30 each). At the moment, the multiple choice questions are represented as a <select>
element, but to improve UX I'd like to change this to radio buttons.
As it's a ModelForm
, I rely on django to automatically create the fields on the form. So while I know it's possible to change each field on the form by doing this:
class SurveyForm(ModelForm):
...
field_one = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())
these definitions don't currently exist, and I'd have to create at least 150 of those definitions. I'm sure there's a better way to override where the widget choice is made (perhaps extending ModelForm?). Or alternatively, could I do this by attaching the widget to the field definition?
I've taken a look through the Django docs and source, but I can't find where the widget is chosen for model fields with a choices
kwarg.
class MyModelForm(ModelForm):
class Meta:
widgets = {
'field_one': forms.RadioSelect(),
}
May be you'd like this:
widgets = {field: forms.RadioSelect() for field in ['field_one', 'field_two']}
My first thought was that you could use formfield_overrides
. However, that won't work, because you only want to override the widget for models.CharField
s that have choices, not all models.CharField
s.
One approach would be to loop through the form's fields in the __init__
method, and change any widgets from forms.Select
to forms.RadioInput
.
class SurveyForm(forms.ModelForm):
class Meta:
model = Survey
fields = ('field_one', 'field_two', ...)
def __init__(self, *args, **kwargs):
super(SurveyForm, self).__init__(*args, **kwargs)
for field in self.fields.values():
if isinstance(field.widget, forms.Select):
field.widget = forms.RadioSelect()
If you have many forms like this, you could extract the functionality into a mixin.
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