__init __()有多个试图覆盖表格的参数值。

时间:2018-06-27 15:48:14

标签: django forms post

我正在尝试覆盖表单以显示对数据的选择,我的问题是当我尝试发送表单时出现此错误 init ()有多个参数值。

form.py

class ChangeMemberForm(forms.Form):
    coordinator = forms.ModelChoiceField(queryset=None,label="Pesquisadores", widget=forms.Select(attrs={'class':'form-control'}))
    def __init__(self,ubc, *args,**kwargs):
        super(ChangeMemberForm, self).__init__(*args,**kwargs)
        ubc = Ubc.objects.get(id=ubc)
        self.fields['coordinator'].queryset = ubc.researchers.all()

view.py

def change_coordinator(request, pk):
    template_name =  'ubc/addmember.html'
    ubc = Ubc.objects.get(pk=pk)
    if request.method == "POST":
        form = ChangeMemberForm(request.POST, ubc=ubc.id)
        if form.is_valid():
            print(form.cleaned_data)
        return redirect('accounts:account_detail', pk=request.user.id)
    form = ChangeMemberForm(ubc=ubc.id)
    context = {
        'form': form,
    }
    return render(request, template_name, context)

2 个答案:

答案 0 :(得分:3)

您定义参数的顺序为:

def __init__(self, ubc, *args, **kwargs):

而您通过以下方式致电__init__

form = ChangeMemberForm(request.POST, ubc=ubc.id)

因此,您使用未命名的第一个参数来调用它,而第一个参数是ubc。因此,__init__函数收到了ubc参数的两个值:request.POSTubc.id,这当然没有意义。

因此您应该将其替换为:

form = ChangeMemberForm(ubc.id, request.POST)

因此,这意味着第一个参数(ubc.id)重定向到ubc参数,第二个(request.POST)是*args的第一个参数,它是super().__init__调用的参数。

答案 1 :(得分:2)

django中的约定是在初始化表单时将表单数据作为第一个位置参数传递。

您的ChangeMemberForm的问题在于,ubc被声明为第一个位置参数。因此,当您尝试ChangeMemberForm(request.POST, ubc=ubc.id)时,两个参数都将被解释为ubc,而python会引发异常。

当您继承Form的子类时,最好将命名参数用于自定义表单类所需的任何其他参数。使用python 3,只需在ubc方法签名中的*args**kwargs之间放置__init__

class ChangeMemberForm(forms.Form):
    def __init__(self, *args, ubc, **kwargs):
        ...

(如果您使用的是python 3.4或更早版本,则必须包含ubc的默认值,如Willem在评论中所述)

如果必须支持python 2,则此语法无效,而必须执行类似的操作。

class ChangeMemberForm(forms.Form):
    def __init__(self, *args, **kwargs):
        ubc = kwargs.pop('ubc')
        ...