django唯一约束违反错误消息消息未处理

4ktjp1zp  于 2023-03-13  发布在  Go
关注(0)|答案(1)|浏览(242)

我有这样一个模型:

class DataMapping(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    location = models.ForeignKey(Location, null=True, blank=True, on_delete=models.CASCADE)
    department = models.ForeignKey(LocationDepartment, null=True, blank=True, on_delete=models.CASCADE)
    catagory = models.ForeignKey(CompanyCategory, on_delete=models.CASCADE)
    reason = models.ForeignKey(ReasonForProcessing, on_delete=models.CASCADE)

        class Meta:
            constraints = [
                UniqueConstraint(
                    name='unique_data_map', 
                    fields=['company', 'location', 'department', 'catagory', 'reason'],
                    condition=Q(location__isnull=False),
                    violation_error_message="This data map has already been added.",
                ),
                UniqueConstraint(
                    name='unique_data_map_both_none_dep_none', 
                    fields=['company', 'location', 'catagory', 'reason'],
                    condition=Q(department__isnull=True),
                    violation_error_message="This data map has already been added."
                ),
                UniqueConstraint(
                    name='unique_data_map_both_none', 
                    fields=['company', 'catagory', 'reason'],
                    condition=Q(location__isnull=True) & Q(department__isnull=True),
                    violation_error_message="This data map has already been added."
                )
    ]

基本的模型

class DataMapForm(forms.ModelForm):
    class Meta:
        model = DataMapping
        fields = (
            'location',
            'department',
            'catagory',
            'reason',
    )
    widgets = {
        'company': forms.HiddenInput()
    }

以及以下视图:

def data_mapping_new(request):
    company = get_current_logged_in_company(request)

    if request.method == "POST":
        form = DataMapForm(request.POST or None)
        if form.is_valid():
            catagory = form.save(commit=False)
            catagory.company = company
            if form.is_valid():
                form.save()

我在不同的模型上有一个类似的设置,工作正常,但这个只是引发了一个错误django.db.utils.IntegrityError: duplicate key value violates unique constraint "unique_data_map_both_none"
它是否应该在第一个if form.is_valid():处检查约束
我错过了什么?

kmbjn2e3

kmbjn2e31#

问题出在form.save(commit=False)行,该行不包括满足模型的Meta类中指定的唯一约束所需的所有字段。调用form.save(commit=False)时,您将创建尚未保存到数据库的DataMapping模型的新示例。然后,您将company字段分配给当前公司。但是您没有将值赋给作为唯一约束一部分的其他字段。
尝试在调用form.save()之前添加这些字段,如下所示:

def data_mapping_new(request):
    company = get_current_logged_in_company(request)

    if request.method == "POST":
        form = DataMapForm(request.POST or None)
        if form.is_valid():
            data_mapping = form.save(commit=False)
            data_mapping.company = company
            data_mapping.location = form.cleaned_data['location']
            data_mapping.department = form.cleaned_data['department']
            data_mapping.catagory = form.cleaned_data['catagory']
            data_mapping.reason = form.cleaned_data['reason']

            
            data_mapping.save()

    # ...

上面的解决方案应该可以工作,但是另外我建议您查看由Sir Willem Van Onsem制作的Using request.POST or None反模式。

相关问题