Django中ModelForm多对多字段数据无法插入问题求助
问题:Vendor模型的ManyToMany字段branch无法保存到数据库
我定义了Branch分支主表模型和Vendor供应商模型,其中Vendor的branch字段为ManyToManyField关联Branch。已创建对应的VendorForm模型表单,在Add_Vendor视图中处理表单提交。当前问题:Vendor基础数据可正常保存,但关联的branch字段数据无法插入数据库。
Branch模型代码
class Branch(models.Model): # Branch Master status_type = ( ("a",'Active'), ("d",'Deactive'), ) code = models.CharField(max_length=100, null=True, blank=True, default=None) name = models.CharField(max_length=100, unique=True) suffix = models.CharField(max_length=8, unique=True) Remark = models.CharField(max_length=200, null=True, blank=True) created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) create_at = models.DateTimeField(auto_now_add=True) update_at = models.DateTimeField(auto_now=True) status = models.CharField(max_length=1, choices = status_type, default = 'a') def __str__(self): return self.name
Vendor模型代码
class Vendor(models.Model): status_type = ( ("a",'Active'), ("d",'Deactive'), ) code = models.CharField(max_length=100, null=True, blank=True, default=None) branch = models.ManyToManyField(Branch) company = models.CharField(max_length=200) name = models.CharField(max_length=200) phone = models.CharField(max_length=11, unique = True) email = models.EmailField(max_length=254, unique = True) gst = models.CharField(max_length=15, unique = True) pan_no = models.CharField(max_length=10, unique = True) add_1 = models.CharField(max_length=50, null=True, blank = True) add_2 = models.CharField(max_length=50, null=True, blank = True) add_3 = models.CharField(max_length=50, null=True, blank = True) city = models.CharField(max_length=50, default=None) state = models.CharField(max_length=50, default=None) Remark = models.CharField(max_length=200, null=True, blank=True) created_by = models.ForeignKey(User, on_delete=models.CASCADE) create_at = models.DateTimeField(auto_now_add=True) update_at = models.DateTimeField(auto_now=True) status = models.CharField(max_length=1, choices = status_type, default = 'a')
forms.py代码
class VendorForm(ModelForm): class Meta: model = Vendor fields = '__all__' labels = { 'add_1':'Address', 'add_2':'Address', 'add_3':'Address', } exclude = ['created_by'] widgets = { 'branch':forms.CheckboxSelectMultiple(attrs={'class':'',}), 'company':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Company Name'}), 'name':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Name'}), 'phone':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Phone'}), 'email':forms.EmailInput(attrs={'class':'form-control', 'placeholder':'Email'}), 'gst':forms.TextInput(attrs={'class':'form-control', 'placeholder':'GST No.'}), 'pan_no':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Pan No.'}), 'add_1':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Address'}), 'add_2':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Address'}), 'add_3':forms.TextInput(attrs={'class':'form-control', 'placeholder':'Address'}), 'city':forms.TextInput(attrs={'class':'form-control', 'placeholder':'City'}), 'state':forms.TextInput(attrs={'class':'form-control', 'placeholder':'State'}), 'Remark':forms.Textarea(attrs={'class':'form-control','rows':'2', 'placeholder':'Remark'}), 'status':forms.Select(attrs={'class':'form-control'}), }
views.py代码
def Add_Vendor(request): # for vendor add if request.method == "POST": try: form = VendorForm(request.POST) if form.is_valid: forms = form.save(commit=False) forms.created_by = request.user forms.save() messages.success(request,'Vendor has been added.') return redirect('vendor_page') except: messages.error(request, str(form.errors)) print(form.errors) else: form = VendorForm() context = { 'form':form, 'branch_data':request.session['branch_name'], 'btn_type':'fa fa-regular fa-plus', 'form_title':'Vendor Form', 'tree_main_title':'Vendor', 'v_url':'vendor_page', 'tree_title':'Add Form', } return render(request, 'base/vendor_master/form_vendor.html', context)
问题原因及修复方法
1. 表单验证逻辑错误
代码中if form.is_valid:只是引用了方法对象,并未执行验证操作,必须改为if form.is_valid():才能触发表单验证,否则后续的关联数据处理逻辑不会执行。
2. 未手动保存ManyToMany关联数据
使用form.save(commit=False)时,Django不会自动保存ManyToMany字段的数据,因为这类数据需要关联已持久化的模型实例。需在保存Vendor基础数据后,调用form.save_m2m()来完成关联数据的插入。
修复后的views.py代码
def Add_Vendor(request): # for vendor add if request.method == "POST": try: form = VendorForm(request.POST) # 修复:执行表单验证,添加括号 if form.is_valid(): # 暂存未提交的Vendor实例 vendor = form.save(commit=False) vendor.created_by = request.user # 保存Vendor基础数据到数据库 vendor.save() # 保存ManyToMany字段的关联数据 form.save_m2m() messages.success(request,'Vendor has been added.') return redirect('vendor_page') else: # 表单验证失败时返回错误 messages.error(request, str(form.errors)) print(form.errors) except Exception as e: messages.error(request, str(e)) print(str(e)) else: form = VendorForm() context = { 'form':form, 'branch_data':request.session['branch_name'], 'btn_type':'fa fa-regular fa-plus', 'form_title':'Vendor Form', 'tree_main_title':'Vendor', 'v_url':'vendor_page', 'tree_title':'Add Form', } return render(request, 'base/vendor_master/form_vendor.html', context)
额外检查点
- 确认模板中branch字段的多选框正确渲染,且在
<form>标签内,提交时能传递选中值 - 排查是否有中间件或权限限制过滤了branch字段的POST数据
内容的提问来源于stack exchange,提问作者shyam rathod
相关产品推荐
相关产品推荐

