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

如何在Django 3.2中正确处理唯一约束引发的IntegrityError

问题需求与解决

需要为模型中的region和subnet_ip字段设置组合唯一约束,且仅当subnet_ip不以172.开头时生效。目前已在数据库层面配置该约束,但提交重复的字段组合时,系统会抛出IntegrityError异常,而非在表单内显示友好的验证提示,需将错误提示改为表单内的验证信息。

模型关键代码

class AggSubnet(models.Model):
    region = models.ForeignKey("db_info.Region", on_delete=models.PROTECT, related_name='get_agg_by_region')
    subnet_ip = models.GenericIPAddressField()

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['subnet_ip','region'], condition=~Q(subnet_ip__startswith='172.'), name='agg_subnet_unique'),
        ]

    def __str__(self):
        return f'{self.region} {self.subnet_ip}/{self.subnet_prefix}' 
    def get_absolute_url(self):
        return reverse(f'{self.__class__.__name__}{DETAIL_SUFFIX}', kwargs={"pk": self.pk})

视图代码

class AggregateSubnetCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = AggregateSubnet
    template_name = 'Subnet_create.html'
    fields = ('region', 'subnet_ip')
    success_message = "%(subnet_ip)s 创建成功"
    def form_valid(self, form): 
        form.instance.created_by = self.request.user
        form.instance.updated_by = self.request.user
        return super().form_valid(form)

已实现的解决方案

通过重写ModelForm的clean方法,在表单层面实现验证逻辑,避免数据库抛出异常:

class AggregateSubnetForm(forms.ModelForm):
    class Meta:
        model = AggregateSubnet
        fields = ('region', 'subnet_ip', 'subnet_prefix',)
    def clean(self):
        cleaned_data = self.cleaned_data
        subnet_ip = cleaned_data['subnet_ip']
        region = cleaned_data['region']
        # 匹配数据库约束的组合逻辑,同时校验region和subnet_ip
        if not subnet_ip.startswith('172.') and AggregateSubnet.objects.filter(subnet_ip=subnet_ip, region=region).exists():
            raise ValidationError(
                ('无效值: %(value)s 该子网已存在。仅以172.开头的私有IP允许重复!'),
                params={'value': subnet_ip},    
            )
        return super().clean()

注:原解决方案未关联region字段进行组合校验,此处补充后确保与数据库约束逻辑一致。

内容的提问来源于stack exchange,提问作者Firdaus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:40:38