为什么指定Widget的选项在ModelForm中不起作用.__ init__

时间:2010-08-07 20:27:03

标签: python django django-forms

我试图理解为什么如果我在Django中覆盖ModelForm的字段,我无法为表单字段的小部件指定选择。如果我给字段选择而不是窗口小部件,它可以工作。我的理解是,如果你给一个字段做出选择,它将被传递到小部件上进行渲染。我知道我可以使用下面的前三个片段中的任何一个,但我只是想完全理解为什么这一种方法不起作用。

这是我的ModelForm代码,谢谢!

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)
                )

1 个答案:

答案 0 :(得分:2)

我认为解释的最佳方式是遍历ChoiceField TypeChoiceFieldclass 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)
            )

举个例子,

super(ChoiceField, self).__init__
  1. 窗口小部件已初始化,其中choices = guest.Choices
  2. self.choices=choices设置self.widget = widget。小部件的选择仍然设置。
  3. ()字段的选项设置为默认_set_choices,因为未指定(请参阅上面的{{1}})。< / LI>

    希望这是有道理的。查看代码还解释了为什么您的其他示例有效。可以同时为窗口小部件和选择字段设置选项,也可以在初始化选择字段后设置窗口小部件的选项。