无法向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
相关产品推荐
相关产品推荐

