Django Form实现唯一值校验提示 解决UNIQUE constraint failed报错
问题原因
你当前的代码存在3处核心错误,才会触发数据库层面的UNIQUE constraint failed报错,同时无法显示前端校验提示:
- 表单类继承错误,且自定义校验逻辑完全不符合需求
- 表单校验失败后直接重定向,丢失了表单错误上下文
- 表单Meta配置的fields参数格式错误
修复步骤
1. 修正表单代码
你要绑定模型做校验,应该继承forms.ModelForm而不是普通forms.Form,同时单字段唯一性校验推荐用clean_字段名方法,逻辑改为查询数据库是否存在重复值:
class CheckoutForm(forms.ModelForm): siret = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Ton SIRET'})) class Meta: model = Company # 元组要加逗号,否则会被识别为字符串 fields = ('siret',) def clean_siret(self): siret = self.cleaned_data.get('siret') # 查询数据库是否已存在该siret if Company.objects.filter(siret=siret).exists(): raise forms.ValidationError("该SIRET已存在") # 正常返回校验后的字段值 return siret
2. 修正视图代码
校验失败后不要重定向,要直接渲染当前 checkout 页面,把带错误信息的表单实例传入模板,这样前端才能拿到错误提示:
def post(self, request, *args, **kwargs): form = CheckoutForm(self.request.POST) if form.is_valid(): # ModelForm可以直接save,不用手动实例化Company company = form.save(commit=False) company.user = self.request.user company.save() context = { 'company': company, } return redirect("core:payment") else: messages.info(self.request, "请正确填写配送表单") # 校验失败返回当前页,传入带错误的form,替换为你实际的checkout模板路径 return render(request, 'checkout.html', {'form': form})
3. 模板代码无需额外修改
你已经用了crispy_forms渲染表单,只要视图传入了带错误的form实例,crispy会自动把校验错误提示渲染在对应输入框的下方,和你要的参考效果完全一致。
内容的提问来源于stack exchange,提问作者tomferrari
相关产品推荐
相关产品推荐

