__init__() 获得多个参数值试图覆盖 forms.Form

问题描述 投票:0回答:2

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

表格.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()

视图.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)
django forms post django-forms
2个回答
4
投票

您定义参数的顺序是:

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

而您拨打

__init__
的方式是:

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

因此您使用未命名的第一个参数来调用它,而第一个参数是

ubc
。因此,
__init__
函数收到了
ubc
参数的两个值:
request.POST
ubc.id
,当然这是没有意义的。

所以你应该将其替换为:

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

所以这里的意思是第一个参数(

ubc.id
)被重定向到
ubc
参数,第二个(
request.POST
)是
*args
的第一个参数,也就是
super().__init__
的参数打电话。


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')
        ...
© www.soinside.com 2019 - 2024. All rights reserved.