【问题标题】:How to handle IntegrityError unique constraint correctly in Django 3.2如何在 Django 3.2 中正确处理 IntegrityError 唯一约束
【发布时间】:2022-11-06 11:12:20
【问题描述】:

你好,我堆满了那个简单的东西。我需要在模型中使用两个字段进行验证 组合必须是唯一的。这些工作几乎随心所欲,但是在我尝试添加新组合之后它在我的表单中引发 IntegrityError 而不是验证错误.有什么办法可以处理吗?

#Model(不是所有字段,但在我的问题中不是必需的):

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 was created successfully"
    def form_valid(self, form): 
        form.instance.created_by = self.request.user
        form.instance.updated_by = self.request.user
        return super().form_valid(form)

我的意思是我可以如何替换: enter image description here 像这样的东西: enter image description here

#更新(解决): #这解决了我的问题。我刚刚覆盖了 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']
        if AggregateSubnet.objects.filter(subnet_ip=subnet_ip).exists() and '172.' not in subnet_ip:
            raise ValidationError(
                ('Invalid value: %(value)s this subnet already exist. Only private ip startswith 172. can be duplicated!'),
                params={'value': subnet_ip},    
            )
        return super().clean()

【问题讨论】:

    标签: django django-models django-views django-forms django-templates


    【解决方案1】:

    将此行添加到您的模型 Meta 类中:

    unique_together = (('subnet_ip', 'region'),)
    

    但保持约束到位。

    您还可以在表单清理过程中添加验证:

    class AggSubnet(models.Model):
    
        def clean(self):
            if self.__class__._default_manager.filter(region=self.region, subnet_ip=self.subnet_ip).exlude(pk=self.pk).exists():
                raise forms.ValidationError(...) 
    

    为了以防万一,我同时使用这三个。

    【讨论】:

    • Thx,它几乎按照您的建议帮助我解决了这个问题。我为我的 cbv 创建 modelForm,并覆盖 clean() 方法
    猜你喜欢
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多