Django中字段在视图赋值时,用CreateView与自定义表单如何校验UniqueConstraint?
问题原因
Django ModelForm的全量校验(包括联合唯一约束校验)逻辑在form_valid方法执行前就已完成。你在form_valid中才为表单实例赋值company字段,表单校验阶段company没有有效值,无法触发定义的UniqueConstraint校验,校验通过后写入数据库时才触发数据库层面的唯一约束,直接抛出500错误。
解决方法
核心逻辑是将company字段的赋值提前到表单校验之前,让表单校验阶段可以拿到完整的字段值触发唯一约束校验,修改方案如下:
- 修改视图逻辑,重写
get_form_kwargs方法,提前给表单实例赋值company,无需再在form_valid中重复赋值:
class ProjectCreateView(LoginRequiredMixin, generic.CreateView): model = Project form_class = ProjectForm def get_form_kwargs(self): kwargs = super().get_form_kwargs() # 初始化实例并提前赋值所属公司 if not kwargs.get('instance'): kwargs['instance'] = Project() kwargs['instance'].company = self.request.user.company return kwargs def form_valid(self, form): return super().form_valid(form)
- 检查表单配置,确保已正确导入
NON_FIELD_ERRORS:
from django.forms import ModelForm, NON_FIELD_ERRORS class ProjectForm(forms.ModelForm): class Meta: model = Project fields = ['name'] error_messages = { NON_FIELD_ERRORS: { 'unique_project_name_in_company': "Name isn't unique!", } }
修改完成后,提交重复项目名时会在校验阶段就捕获唯一约束冲突,返回表单页并展示自定义错误提示,不会再触发500错误。
内容的提问来源于stack exchange,提问作者Fedіr Yatsenko
相关产品推荐
相关产品推荐

