Django Inline Formset如何自动设置当前用户到表单字段解决非空报错
问题原因
你遇到的报错是因为两个关键逻辑错误:
- 你在
HeadfttlogDeafttlogEditView中自定义了formset_valid方法,但FormView类校验表单成功后默认调用的是form_valid方法,你写的用户赋值逻辑根本没有被执行。 - 你直接给formset整体赋值
dea_creator属性是无效的,formset是多个子表单的集合,每个子表单对应一条Deafttlog记录,需要逐个给每条记录的实例赋值用户字段。
解决方案
第一步(可选,推荐):优化表单配置,避免前端篡改用户字段
修改forms.py中的HeadfttlogDeafttlogFormset定义,把dea_creator、dea_modifier从字段列表中移除,这两个字段完全由后端赋值,不需要暴露给前端:
HeadfttlogDeafttlogFormset = inlineformset_factory(Headfttlog, Deafttlog, fields=('dea_linetype', 'dea_fttlcode', 'dea_airportfrom', 'dea_airportto', 'dea_instrtimestart', 'dea_instrtimeend', 'dea_instrtimetot', 'dea_blocktimestart', 'dea_blocktimeend', 'dea_blocktimetot', 'dea_flighttimestart', 'dea_flighttimeend', 'dea_flighttimetot', 'dea_approach', 'dea_landing', 'dea_external', 'dea_fuel', 'dea_oil', 'dea_lessonnotes', 'dea_preflightsignature', 'dea_invoiceaccount', 'dea_transfered', 'dea_transfereddate', 'dea_reccanceled'), widgets={ 'dea_instrtimestart' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_instrtimeend' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_instrtimetot' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_blocktimestart' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_blocktimeend' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_blocktimetot' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_flighttimestart' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_flighttimeend' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_flighttimetot' : forms.TimeInput(format= '%H:%M', attrs={'type': 'time'}), 'dea_reccanceled' : forms.HiddenInput, }, extra=1, max_num=8)
如果不想修改表单字段配置,跳过这一步即可,后续赋值逻辑会覆盖前端提交的隐藏字段值。
第二步:修改视图逻辑,正确给每个子表单赋值用户
替换views.py中HeadfttlogDeafttlogEditView类里的formset_valid方法,重命名为form_valid,并新增遍历赋值逻辑:
def form_valid(self, form): # 先获取所有待保存的实例,不直接提交到数据库 instances = form.save(commit=False) for instance in instances: # 新增的记录没有主键,填充创建人 if not instance.pk: instance.dea_creator = self.request.user # 所有新增/修改的记录都填充修改人 instance.dea_modifier = self.request.user instance.save() # 保存formset的多对多关联(没有多对多字段也可正常执行) form.save_m2m() messages.add_message( self.request, messages.SUCCESS, 'Changes were saved.' ) return HttpResponseRedirect(self.get_success_url())
修改完成后重新运行项目即可正常保存,不会再报用户字段不能为空的错误。
内容的提问来源于stack exchange,提问作者NewDevAsks1
相关产品推荐
相关产品推荐

