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

Posted

技术标签:

【中文标题】__init__() 有多个参数值试图覆盖 forms.Form【英文标题】:__init__() got multiple values for argument trying to override forms.Form 【发布时间】:2018-12-06 14:11:10 【问题描述】:

我正在尝试覆盖我的表单以显示带有我的数据的选择,我的问题是当我尝试发送表单时我收到此错误 init() got multiple values for argument。

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)

【问题讨论】:

【参考方案1】:

你定义参数的顺序是:

def __init__(self<b>, ubc, *args</b>, **kwargs):

而您通过以下方式致电__init__

<s>form = ChangeMemberForm(request.POST<b>, ubc=ubc.id</b>)</s>

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

所以你应该把它替换为:

form = ChangeMemberForm(<b>ubc.id,</b> request.POST)

所以这里的意思是第一个参数(ubc.id)重定向到ubc参数,第二个(request.POST)是*args的第一个参数,是@的一个参数987654334@电话。

【讨论】:

您也可以将data 作为命名参数传递。然后顺序无关紧要。 ChangeMemberForm(data=request.POST, ubc=ubc.id) 感谢您的帮助【参考方案2】:

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

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

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

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')
        ...

【讨论】:

这对于较低的Python-3.x版本实际上是无效的语法,因为在*args之后,所有未命名的参数都用完了,因此ubc需要有一个默认值。 感谢您的帮助

以上是关于__init__() 有多个参数值试图覆盖 forms.Form的主要内容,如果未能解决你的问题,请参考以下文章

NotImplementedError:在 `__init__` 中有参数的层必须覆盖 `get_config`

python构造函数

覆盖 Django 模型 __init__ 方法

如何掩盖 PyTorch 权重参数中的权重?

Graphql 试图创建 get_user_model 的对象:__init__() 得到了一个意外的关键字参数“请求”

使用多个 __init__ 参数子类化元组