不再显示Django rest框架唯一的错误消息

时间:2020-07-15 09:48:42

标签: python django django-rest-framework

我使用django rest框架工作了很多,直到今天一切工作都很好。相同的函数突然返回不同的东西。我的客户模型上有一个唯一的名称和公司名称。我最近创建了一个名为AutoCompany的混入,该混入会自动在客户端上设置公司。

我的客户模型:

class Client(AutoCompany):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=155)
    description = models.TextField(blank=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=["name", "company"], name="Name and company"),
        ]

AutoCompany


class AutoCompany(models.Model):
    company = models.ForeignKey("company.Company", models.DO_NOTHING)

    def save(self, *args, **kwargs):
        company = apps.get_model("company.Company")

        try:
            self.company
        except company.DoesNotExist:
            self.company = get_request().user.company

        self.after_company_set()

        return super().save(*args, **kwargs)

    def after_company_set(self):
        pass

    class Meta:
        abstract = True

所以以前,当我为同一家公司创建一个具有相同名称的客户时,我收到400错误的响应:

The fields name, company must make a unique set.

我的序列化器如下:

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Client
        fields = ["id", "name", "description"]

但是现在我只得到500响应,并显示python错误。似乎错误不再存在。现在我得到:

django.db.utils.IntegrityError: (1062, "Duplicate entry 'test-cafd0ed10f9f4865a1d56abb67daa831' for key 'Name and company'")

有人知道为什么会发生这种变化吗?

1 个答案:

答案 0 :(得分:1)

DRF不能像UniqueConstraint那样验证unique_together

之所以这样做,是因为唯一约束比“该字段集合必须具有唯一值”要复杂得多。请考虑以下内容:

UniqueConstraint(
    fields=["author", "slug"],
    condition=Q(status="published"),
    name="author_slug_published_uniq",
)

此约束仅在状态为published时验证该行是唯一的,即,如果所有行都是草稿,则可以有多个行具有相同的段和作者。由于这种复杂性,因此没有验证器。但是,对于这种简单情况,您可以手动添加DRF's UniqueTogether validator

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ["id", "name", "description", "company"]
        validators = [
            UniqueTogetherValidator(
                queryset=Client..objects.all(),
                fields=["name", "company"],
            )
        ]