I’m trying to understand why I can’t specify choices to a form field’s widget if I’m overriding a ModelForm’s field in Django. It works if I give the choices to the field but not the widget. My understanding is/was that if you give choices to a field it’ll be passed onto the widget for rendering. I know I can get this to work with any of the first three snippets below but I just wanted to fully understand why this one way doesn’t work.
This is my ModelForm code, thanks!
from django import forms
from models import Guest
class RSVPForm(forms.ModelForm):
class Meta:
model = Guest
def __init__(self, *args, **kwargs):
"""
Override a form's field to change the widget
"""
super(RSVPForm, self).__init__(*args, **kwargs)
# This works
self.fields['attending_ceremony'].required = True
self.fields['attending_ceremony'].widget=forms.RadioSelect(choices=Guest.CHOICES)
# This works
self.fields['attending_ceremony'].required = True
self.fields['attending_ceremony'].widget=forms.RadioSelect()
self.fields['attending_ceremony'].choices=Guest.CHOICES
# This works
self.fields['attending_ceremony'] = forms.TypedChoiceField(
required=True,
widget=forms.RadioSelect,
choices=Guest.CHOICES
)
# This doesn't - the choices aren't set (it's an empty list)
self.fields['attending_ceremony'] = forms.TypedChoiceField(
required=True,
widget=forms.RadioSelect(choices=Guest.CHOICES)
)
I think the best way of explaining is to walk through the code for
ChoiceField, the superclass ofTypeChoiceField.With your example,
super(ChoiceField, self).__init__sets self.widget=widget. The widget’s choices are still set.self.choices=choicessets the choices for the field and the widget to the default(), because it wasn’t specified (see_set_choicesabove).Hope that makes sense. Looking at the code also explains why your other examples work. Either the choices are set for the widget and the choice field at the same time, or widget’s choices are set after the choice field has been initialised.