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

