我正在尝试覆盖我的表单以显示带有我的数据的选择,我的问题是当我尝试发送表单时,我收到此错误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)
您定义参数的顺序是:
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__
的参数打电话。
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')
...