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

Django inline formset未被用户修改时不保存默认值问题求助

问题根源

Django FormSet 内置逻辑默认会忽略未发生任何字段变更的表单,判定为不需要执行数据库操作,save() 方法不会返回这类未修改的实例。
你当前属于新建父模型 Patient 的场景,FormSet 初始化时未绑定已存在的父实例,未修改的子表单会被识别为无效待跳过对象,调用 save(commit=False) 自然返回空列表。


解决方案

方案1:修改FormSet定义(最简单,适配你的场景)

在创建inlineformset时添加form_kwargs={'empty_permitted': False}参数,禁止表单被判定为“空”跳过,就算是默认值未修改也会被正常识别为待保存对象。
修改forms.py中的FormSet定义:

SevseffFormSet = inlineformset_factory(
    Patient,
    SeVsEff,
    fields=("value",),
    widgets={'value': RangeInput()},
    extra=0,
    min_num=1,
    validate_min=True,
    labels=None,
    form_kwargs={'empty_permitted': False} # 新增该行配置
)

修改后无需改动视图逻辑,未修改默认值的表单也会正常生成实例保存。


方案2:视图层手动补全逻辑(适配更复杂的自定义场景)

如果不想修改FormSet全局配置,可以在视图中单独处理无变更的场景,从合法表单的cleaned_data中取值手动创建子实例。
修改views.py中的post方法逻辑:

def post(self, *args, **kwargs):
    form = PatientForm(data=self.request.POST)
    sevseff_formset = SevseffFormSet(data=self.request.POST)

    # 先同时校验父子表单,避免生成父实例后子表单不合法的脏数据
    if form.is_valid() and sevseff_formset.is_valid():
        patient_instance = form.save(commit=False)
        patient_instance.user = self.request.user
        patient_instance.save()

        # 处理有变更的子表单
        sevseff_instances = sevseff_formset.save(commit=False)
        for sevseff in sevseff_instances:
            sevseff.patient = patient_instance
            sevseff.save()
        
        # 无变更时手动创建子实例
        if not sevseff_instances:
            for valid_form in sevseff_formset.forms:
                if valid_form.cleaned_data:
                    SeVsEff.objects.create(
                        patient=patient_instance,
                        value=valid_form.cleaned_data['value']
                    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:45:03