Django Rest框架独特的一起错误消息不再显示

Jes*_*ong 3 python django django-rest-framework

我经常使用 Django Rest 框架,直到今天一切都运行良好。同一个函数突然返回不同的东西。我的客户模型上有一个独特的名称和公司。我最近创建了一个名为 AutoCompany 的 mixin,它会自动在客户端设置公司。

我的客户型号:

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"),
        ]
Run Code Online (Sandbox Code Playgroud)

汽车公司


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
Run Code Online (Sandbox Code Playgroud)

因此,之前当我为同一家公司创建同名的客户端时,我收到了包含以下错误的 400 响应:

The fields name, company must make a unique set.
Run Code Online (Sandbox Code Playgroud)

我的序列化器如下所示:

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

但现在我只收到一个带有 python 错误的 500 响应。似乎错误不再被捕获。现在我只得到:

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

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

Tom*_*ick 10

DRF 并不UniqueConstraint像它那样进行验证unique_together

这样做的原因是因为唯一约束可能比“该字段集合必须具有唯一值”更复杂。考虑以下:

UniqueConstraint(
    fields=["author", "slug"],
    condition=Q(status="published"),
    name="author_slug_published_uniq",
)
Run Code Online (Sandbox Code Playgroud)

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

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