如何将选项传递给ChoiceField?

我有一个charfield和choicefield的多值域。 我需要将选择传递给choicefield构造函数,但是当我尝试将其传递到自定义多值字段时,出现错误__init__()得到了一个意外的关键字参数'choices'。

我知道其余代码的工作原理,因为当我从__init__和super中删除choices关键字参数时,多值字段显示正确,但没有任何选择。

这是我如何设置我的自定义多值字段:

class InputAndChoice(object):
    def __init__(self, text_val='', choice_val=''):
        self.text_val=text_val
        self.choice_val=choice_val

class InputAndChoiceWidget(widgets.MultiWidget):
    def __init__(self, attrs=None):
        widget = (widgets.TextInput(),
                  widgets.Select()
                 )
        super(InputAndChoiceWidget, self).__init__(widget, attrs=attrs)

    def decompress(self,value):
        if value:
            return [value.text_val, value.choice_val]
        return [None, None]


class InputAndChoiceField(forms.MultiValueField):
    widget = InputAndChoiceWidget

    def __init__(self, required=True, widget=None, label=None, initial=None,
                 help_text=None, choices=None):
        field = (
                 fields.CharField(),
                 fields.ChoiceField(choices=choices),
                 )
        super(InputAndChoiceField, self).__init__(fields=field, widget=widget, 
              label=label, initial=initial, help_text=help_text, choices=choices)

我这样称呼它:

input_and_choice = InputAndChoiceField(choices=[(1,'first'),(2,'second')])

那么如何将选项传递给我的ChoiceField字段?

编辑:

我试过了stefanw的建议,但仍然没有运气。 我已经使用logging.debug在init和self.fields [1]的末尾打印出InputAndChoiceField的内容。[1] .choices包含上述正确的值,但它不会在浏览器中显示任何选项。


我遇到了这个完全相同的问题,并解决了这个问题:

class InputAndChoiceWidget(widgets.MultiWidget):
    def __init__(self,*args,**kwargs):
        myChoices = kwargs.pop("choices")
        widgets = (
            widgets.TextInput(),
            widgets.Select(choices=myChoices)
        )
        super(InputAndChoiceWidget, self).__init__(widgets,*args,**kwargs)

class InputAndChoiceField(forms.MultiValueField):
    widget = InputAndChoiceWidget

    def __init__(self,*args,**kwargs):
        # you could also use some fn to return the choices;
        # the point is, they get set dynamically 
        myChoices = kwargs.pop("choices",[("default","default choice")])
        fields = (
            fields.CharField(),
            fields.ChoiceField(choices=myChoices),
        )
        super(InputAndChoiceField,self).__init__(fields,*args,**kwargs)
        # here's where the choices get set:
        self.widget = InputAndChoiceWidget(choices=myChoices)

为widget的构造函数添加一个“选择”kwarg。 然后在创建字段后显式调用构造函数。


查看forms.MultiValueField__init__的源代码:

def __init__(self, fields=(), *args, **kwargs):
    super(MultiValueField, self).__init__(*args, **kwargs)
    # Set 'required' to False on the individual fields, because the
    # required validation will be handled by MultiValueField, not by those
    # individual fields.
    for f in fields:
        f.required = False
    self.fields = fields

所以我会覆盖__init__可能是这样的:

def __init__(self, *args, **kwargs):
    choices = kwargs.pop("choices",[])
    super(InputAndChoiceField, self).__init__(*args, **kwargs)
    self.fields = (
        fields.CharField(),
        fields.ChoiceField(choices=choices),
    )

你甚至可能想要做super(MultiValueField, self).__init__(*args, **kwargs)而不是super(InputAndChoiceField, self).__init__(*args, **kwargs)因为你自己设置字段而不是获取他们通过参数。


通过小部件中的选择为我解决了这个问题

class InputAndChoiceWidget(widgets.MultiWidget):
    def __init__(self, attrs=None):
        choices = [('a', 1), ('b', 2)]
        widget = (widgets.TextInput(),
                  widgets.Select(choices=choices)
                 )
        super(InputAndChoiceWidget, self).__init__(widget, attrs=attrs)
链接地址: http://www.djcxy.com/p/43483.html

上一篇: How to pass choices to ChoiceField?

下一篇: HasResolution typeclass