Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么在ModelForm中为小部件指定选项不起作用___Python_Django_Django Forms - Fatal编程技术网

Python 为什么在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

我试图理解,如果在Django中重写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)
                )

我认为最好的解释方法是遍历
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)。\uuuuu init\uuuu
    设置self.widget=widget。小部件的选项仍处于设置状态
  • self.choices=choices
    将字段和小部件的选项设置为默认值
    ()
    ,因为没有指定它(请参见上文的
    \u set\u choices

  • 希望这是有道理的。查看代码还可以解释其他示例工作的原因。要么同时为小部件和选择字段设置选项,要么在选择字段初始化后设置小部件的选项。

    哦,好的,我同意你的意见。由于未指定字段的选项,它将被覆盖。谢谢