我正在尝试覆盖表单以显示对数据的选择,我的问题是当我尝试发送表单时出现此错误 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)
答案 0 :(得分:3)
您定义参数的顺序为:
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__
调用的参数。
答案 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')
...