Я думаю, что лучший способ объяснить это пройти через код для ChoiceField
, суперкласс TypeChoiceField
.
class ChoiceField(Field):
widget = Select
default_error_messages = {
'invalid_choice': _(u'Select a valid choice. %(value)s is not one of the available choices.'),
}
def __init__(self, choices=(), required=True, widget=None, label=None,
initial=None, help_text=None, *args, **kwargs):
super(ChoiceField, self).__init__(required=required, widget=widget, label=label,
initial=initial, help_text=help_text, *args, **kwargs)
self.choices = choices
def _get_choices(self):
return self._choices
def _set_choices(self, value):
# Setting choices also sets the choices on the widget.
# choices can be any iterable, but we call list() on it because
# it will be consumed more than once.
self._choices = self.widget.choices = list(value)
choices = property(_get_choices, _set_choices)
На вашем примере
self.fields['attending_ceremony'] = forms.TypedChoiceField(
required=True,
widget=forms.RadioSelect(choices=Guest.CHOICES)
)
- Виджет инициализирован, с выбором = guest.Choices
super(ChoiceField, self).__init__
устанавливает self.widget = виджет. Выбор виджета по-прежнему установлен.
self.choices=choices
устанавливает для поля и виджета значение по умолчанию ()
, поскольку оно не было указано (см. _set_choices
выше).
Надеюсь, это имеет смысл. Глядя на код также объясняет, почему ваши другие примеры работают. Либо выбор устанавливается для виджета и поля выбора одновременно, либо выбор виджета устанавливается после инициализации поля выбора.