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

无法向inlineformset_factory传递kwarg参数?Django报错求助

问题:向inlineformset_factory传递kwargs时触发__init__() got an unexpected keyword argument 'form_kwargs'错误

我在Stack Overflow找到相关回答但无法解决问题,按Django官方文档操作也触发相同错误。环境信息:Django==4.1.6、Python 3.9.12、Fedora 37。

视图类代码(含错误标注)

class InvoiceCreateView(CreateView):
    model = Invoice
    fields = (
        'client',
        'order_number',
    )
    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
########## ERROR MESSAGE "__init__() got an unexpected keyword argument 'form_kwargs'"
        kwargs['form_kwargs'] = {'request': self.request}
##########
        return kwargs

    def get_context_data(self, **kwargs):
        data = super(InvoiceCreateView, self).get_context_data(**kwargs)
        if self.request.POST:
            data['track_formset'] = InvoiceFormSet(self.request.POST)
        else:
            data['track_formset'] = InvoiceFormSet()
        return data

    def get_object(self, queryset=None):
        return get_object_or_404(self.model, username=self.request.user.pk)

    def get(self, request, *args, **kwargs):
        self.referer = request.META.get("HTTP_REFERER", "")
        request.session["login_referer"] = self.referer
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.referer = request.session.get("login_referer", "")
        return super().post(request, *args, **kwargs)

    def form_valid(self, form):
        up = UserProfile.objects.get(username=self.request.user.pk)
        form.instance.profile = up
        bk = BankAccount.objects.get(profile=up)
        form.instance.user_bank = bk

        context = self.get_context_data(form=form)
        formset = context['track_formset']
        if formset.is_valid():
            response = super().form_valid(form)
            formset.instance = self.object
            formset.save()
            return response
        else:
            return super().form_invalid(form)
    def get_success_url(self):
        return self.request.path

表单代码(无错误,补充说明)

class InvoiceForm(forms.ModelForm):
    name = forms.CharField(label='Description', initial='Some info')
    class Meta:
        model=Invoice
        exclude = ["username", "invoice_number", "invoice_status", "profile", 
                   "user_bank", "date_from", "date_to","total",]
        model=LineItem
#        readonly_fields = ['total'] # currency default changes if this is set
        exclude = ["user",]

InvoiceFormSet = inlineformset_factory(
    Invoice,
    LineItem,
    form=InvoiceForm,
    min_num=1,  # minimum number of forms that must be filled in
    extra=1,  # number of empty forms to display
    can_delete=False
)

解决方法

1. 让表单支持接收request参数

修改InvoiceForm,添加__init__方法来接收并保存request,同时修正Meta类里重复定义的model字段:

class InvoiceForm(forms.ModelForm):
    name = forms.CharField(label='Description', initial='Some info')
    
    def __init__(self, *args, **kwargs):
        # 从kwargs中取出request,没有则设为None
        self.request = kwargs.pop('request', None)
        super().__init__(*args, **kwargs)
    
    class Meta:
        model=LineItem
        exclude = ["user",]

2. 移除视图中错误的get_form_kwargs方法

删掉视图里的get_form_kwargs方法——这个方法是给CreateView的主表单(对应Invoice模型)传递参数,但主表单并不需要form_kwargs,强行添加会导致主表单初始化报错。

3. 初始化表单集时传递form_kwargs

修改视图的get_context_data方法,在创建表单集实例时传入form_kwargs:

def get_context_data(self, **kwargs):
    data = super(InvoiceCreateView, self).get_context_data(**kwargs)
    formset_kwargs = {'form_kwargs': {'request': self.request}}
    if self.request.POST:
        data['track_formset'] = InvoiceFormSet(self.request.POST, **formset_kwargs)
    else:
        data['track_formset'] = InvoiceFormSet(**formset_kwargs)
    return data

这样修改后,表单集里的每个InvoiceForm实例都会接收到request参数,同时不会再触发原来的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:44:56