Python 为什么在ModelForm中为小部件指定选项不起作用__
我试图理解,如果在Django中重写ModelForm的字段,为什么不能为表单字段的小部件指定选项。如果我给字段(而不是小部件)提供选择,它就可以工作。我的理解是,如果你给一个字段选择,它将被传递到小部件上进行渲染。我知道我可以用下面的前三个片段中的任何一个来实现这一点,但我只是想完全理解为什么这种方法行不通 这是我的模型代码,谢谢Python 为什么在ModelForm中为小部件指定选项不起作用__,python,django,django-forms,Python,Django,Django Forms,我试图理解,如果在Django中重写ModelForm的字段,为什么不能为表单字段的小部件指定选项。如果我给字段(而不是小部件)提供选择,它就可以工作。我的理解是,如果你给一个字段选择,它将被传递到小部件上进行渲染。我知道我可以用下面的前三个片段中的任何一个来实现这一点,但我只是想完全理解为什么这种方法行不通 这是我的模型代码,谢谢 from django import forms from models import Guest class RSVPForm(forms.ModelF
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)
)
我认为最好的解释方法是遍历
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)
)
super(ChoiceField,self)。\uuuuu init\uuuu
设置self.widget=widget。小部件的选项仍处于设置状态self.choices=choices
将字段和小部件的选项设置为默认值()
,因为没有指定它(请参见上文的\u set\u choices
)希望这是有道理的。查看代码还可以解释其他示例工作的原因。要么同时为小部件和选择字段设置选项,要么在选择字段初始化后设置小部件的选项。哦,好的,我同意你的意见。由于未指定字段的选项,它将被覆盖。谢谢