Django关联外键表单保存时NOT NULL约束失败错误求助
问题分析与解决方案
错误原因
出现NOT NULL constraint failed: crm_project.address_id错误的核心问题是数据保存顺序错误,且直接操作表单对象而非模型实例:
- 你尝试给
form_project(表单对象)关联未保存到数据库的address实例,此时address还没有主键ID,无法满足Project模型中address字段的非空约束; - 直接修改表单对象的字段是无效操作,应该对
commit=False返回的模型实例进行赋值。
修正后的视图代码
def add_project(request): form_address = AddressForm(request.POST or None) form_project = ProjectForm(request.POST or None) form_detail = ProjectDetailForm(request.POST or None) if request.method == 'POST': if form_address.is_valid() and form_project.is_valid() and form_detail.is_valid(): # 1. 先保存地址到数据库,获取带主键的address实例 address = form_address.save() # 2. 处理Project:先获取未保存的模型实例,再赋值关联字段 project = form_project.save(commit=False) project.manager = request.user project.address = address # 此时address已存在主键,可正常关联 project.save() # 3. 处理ProjectDetail:关联已保存的project实例后保存 detail = form_detail.save(commit=False) detail.project = project detail.save() context = {'form_address':form_address, 'form_project':form_project, 'form_detail':form_detail,} return render(request, 'crm/project_form.html', context)
额外优化建议
原AddressForm中的__init__方法存在冗余代码,弹出的city参数未使用,且ModelForm会自动为ForeignKey字段生成ModelChoiceField,可简化表单代码:
class AddressForm(forms.ModelForm): class Meta: model = Address fields = ["city", "street", "numb"]
内容的提问来源于stack exchange,提问作者nikar
相关产品推荐
相关产品推荐

