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

Django Inline Formset如何自动设置当前用户到表单字段解决非空报错

问题原因

你遇到的报错是因为两个关键逻辑错误:

  1. 你在HeadfttlogDeafttlogEditView中自定义了formset_valid方法,但FormView类校验表单成功后默认调用的是form_valid方法,你写的用户赋值逻辑根本没有被执行。
  2. 你直接给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:15:04