You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Form实现唯一值校验提示 解决UNIQUE constraint failed报错

问题原因

你当前的代码存在3处核心错误,才会触发数据库层面的UNIQUE constraint failed报错,同时无法显示前端校验提示:

  1. 表单类继承错误,且自定义校验逻辑完全不符合需求
  2. 表单校验失败后直接重定向,丢失了表单错误上下文
  3. 表单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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 06:48:00