You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django表单提交报错:__init__() 参数'user'收到多个值

解决Django表单初始化时的参数冲突问题

问题现象

在实现带用户筛选的ModelChoiceField时,自定义表单__init__方法后,提交表单出现错误:

"init() got multiple values for argument 'user'"

错误原因

表单的__init__方法将user作为位置参数放在了*args前面,而Django表单初始化时,第一个位置参数默认接收表单数据(比如POST请求的request.POST)。当调用WorkLogForm(request.POST, user=request.user)时,request.POST会被赋值给user参数,同时又通过关键字参数传递了user=request.user,导致同一个参数被重复传递,引发冲突。

解决方案

修改forms.py的__init__方法

将user改为从关键字参数中获取,避免位置参数冲突:

class WorkLogForm(forms.ModelForm):
    worklog_date = forms.DateField(label='Дата', widget=forms.DateInput(
        attrs={'class': 'form-control', 'placeholder': 'Введите дату'}))
    author = forms.EmailField(label='Автор',
                              widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email автора'}))

    contractor_counter = forms.ModelChoiceField(queryset=CounterParty.objects.none())
    contractor_object = forms.ModelChoiceField(queryset=ObjectList.objects.none())
    contractor_section = forms.ModelChoiceField(queryset=SectionList.objects.none())

    description = forms.CharField(label='Описание',
                                  widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Описание'}))

    def __init__(self, *args, **kwargs):
        # 从关键字参数中取出user,确保调用时必传
        user = kwargs.pop('user')
        super().__init__(*args, **kwargs)
        
        counter_queryset = CounterParty.objects.filter(counter_user=user)
        object_queryset = ObjectList.objects.filter(
            Q(customer_guid__in=counter_queryset) | Q(contractor_guid__in=counter_queryset))
        section_queryset = SectionList.objects.filter(object__in=object_queryset)

        self.fields['contractor_counter'].queryset = counter_queryset
        self.fields['contractor_object'].queryset = object_queryset
        self.fields['contractor_section'].queryset = section_queryset

    class Meta:
        model = WorkLog
        fields = (
            'worklog_date', 'author', 'contractor_counter', 'contractor_object', 'contractor_section', 'description')

修正views.py中的赋值错误

原代码中直接修改form.author的方式不符合Django表单规范,应通过save(commit=False)修改实例:

def create_work_log(request):
    if request.method == 'POST':
        form = WorkLogForm(request.POST, user=request.user)
        if form.is_valid():
            work_log = form.save(commit=False)
            # 若author字段存储邮箱,赋值request.user.email;若为User外键,直接赋值request.user
            work_log.author = request.user.email
            work_log.save()
            return render(request, 'common/home.html')
    else:
        form = WorkLogForm(user=request.user)

    return render(request, 'contractor/create_work_log.html', {'form': form})

说明

修改后,无论GET还是POST请求,调用表单时都通过关键字参数user=request.user传递用户,既避免了参数冲突,也符合Django表单的初始化规范。

内容的提问来源于stack exchange,提问作者Zesshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:46:04