Django通过form传递的formset插入数据时NOT NULL约束失败问题
错误原因
- 核心问题:没有接收
form.save(commit=False)返回的模型实例,而是直接给Form对象赋值自定义属性,赋值逻辑根本没有作用到要保存的数据库记录上。
你遍历gruppi_formset得到的每个gruppi是表单实例,不是模型实例。调用gruppi.save(commit=False)会返回待保存的模型对象,你没有用变量承接这个返回值,后续给gruppi.gruppi_scheda赋值本质是给表单对象加了个无关属性,模型实例的gruppi_scheda字段还是空的,最终保存触发非空约束报错。 - 潜在隐患:当前你通过
Schede.objects.get(nome_scheda = schedaName)查询关联对象属于冗余查询,且如果nome_scheda字段没有唯一约束,可能出现返回多条记录的异常。 - 额外场景问题:Django formset默认会生成1个空的额外表单,如果用户没有填写该表单内容,遍历的时候也会生成空的模型实例,容易触发各类字段约束报错。
可行解决方案
1. 修正核心赋值逻辑
承接save(commit=False)返回的模型实例,给模型实例赋值外键后再保存,同时过滤无效表单避免脏数据,修改后的循环代码如下:
if gruppi_formset.is_valid(): for gruppi_form in gruppi_formset: # 过滤空表单、标记为删除的表单 if not gruppi_form.cleaned_data or gruppi_form.cleaned_data.get('DELETE'): continue # 承接待保存的模型实例 gruppi_instance = gruppi_form.save(commit=False) # 直接复用前面已经保存的scheda对象,无需额外查询 gruppi_instance.gruppi_scheda = scheda gruppi_instance.save()
2. 可选:调整formset配置
如果不需要默认生成的空表单,可以在定义formset时设置extra=0,减少无效的遍历判断逻辑。
内容的提问来源于stack exchange,提问作者user15374373
相关产品推荐
相关产品推荐

