如何将request等关键字参数传入Django的inlineformset_factory
问题解决方法
错误根源
你遇到的报错是因为 inlineformset_factory 生成的表单集类本身的__init__方法不接受request参数,你直接在视图的get_form_kwargs中将request塞入参数列表传给表单集,就会触发「意外关键字参数」的报错。request参数需要传递给表单集里的每一个子表单,而不是表单集本身。
方案1:使用Django原生form_kwargs参数(推荐,适用于Django 2.0+)
Django的表单集原生支持通过form_kwargs参数向所有子表单传递自定义参数,不需要额外自定义表单集类:
第一步:修正视图代码
- 删掉
get_form_kwargs方法中添加request的代码 - 在
get_form方法中把request放入form_kwargs传递给表单集 - 修正你现有代码中的其他bug:
post方法错误调用父类get、form_valid漏写return、messages方法漏传request参数
修正后的视图核心代码如下:
# 删掉这个方法里加request的逻辑 def get_form_kwargs(self): kwargs = super().get_form_kwargs() return kwargs def get_form(self, form_class=None): # 给子表单传递的参数放form_kwargs里 form_kwargs = {"request": self.request} return SummativeScoreInlineFormset( **self.get_form_kwargs(), instance=self.object, form_kwargs=form_kwargs ) # 修正post方法,不要调用父类get def post(self, request, *args, **kwargs): summative_id = kwargs.pop("summative_id") self.object = self.get_object( queryset=Summative.objects.filter(id=summative_id) ) return super().post(request, *args, **kwargs) # 修正form_valid方法,补全return和messages参数 def form_valid(self, form): form.save() messages.add_message(self.request, messages.SUCCESS, "Changes were saved!") return HttpResponseRedirect(self.get_success_url())
方案2:自定义表单集类(适用于低版本Django)
如果你的Django版本低于2.0不支持form_kwargs,可以重写表单集的构造方法,手动把request传递给每个子表单:
第一步:在forms.py中自定义基础表单集类
from django.forms import BaseInlineFormSet class BaseSummativeScoreInlineFormset(BaseInlineFormSet): def __init__(self, *args, **kwargs): self.request = kwargs.pop("request", None) super().__init__(*args, **kwargs) def construct_form(self, i, **kwargs): # 给每个子表单传递request if self.request is not None: kwargs["request"] = self.request return super().construct_form(i, **kwargs)
第二步:修改formset生成逻辑,指定自定义的表单集类
SummativeScoreInlineFormset = inlineformset_factory( Summative, SummativeScore, fields=("subdomain_proficiency_level",), can_delete=False, extra=0, form=SummativeScoreForm, formset=BaseSummativeScoreInlineFormset, # 新增这行 )
第三步:保留视图中get_form_kwargs的request传递逻辑
你原来写的get_form_kwargs中添加request的代码可以保留,自定义表单集会处理这个参数。同时依然要修正前面提到的post方法、form_valid方法的bug。
内容的提问来源于stack exchange,提问作者Hanny
相关产品推荐
相关产品推荐

