DRF-在创建和/或验证对象时检查具体的唯一约束冲突



我有一个表,其中在DB和Django级别都设置了复合唯一索引。第一个问题是,我如何在DRF中发现IntegrityError正是因为这个给定的唯一约束违反而上升的?

我遇到了这样一个代码片段:

class TestModel(models.Model):
class Meta:
managed = False
db_table = 'test_table'
unique_together = ('fieldA','fieldB',)
class TestSerializer(serializers.ModelSerializer):
def create(self, request, *args, **kwargs):
try:
return super().create(request, *args, **kwargs)
except IntegrityError as err:
if err.__cause__.pgcode == errorcodes.UNIQUE_VIOLATION:
# Do something special

但这会让步,除此之外,我觉得这不是实现目标的最合适的方式。有什么想法吗?

第二个问题是,如何针对相同的约束进行验证?验证方法中的if条件应该是什么样子?应该在验证方法中还是在其他地方进行?

每种类型的验证都应该在DRF验证方法中进行,即validateis_valid。对于您的情况,您应该在验证方法中检查是否有任何对象已经存在于提供的数据中,如

def is_valid(self, raise_exception=True):
data = self.initial_data
if TestModel.objects.filter(fieldA=data.get('fieldA'), fieldB=data.get('fieldB').exists():
raise serializers.ValidationError("Object already exist with {fieldA} and {fieldB}".format(**data)
return super().is_valid(raise_exception)

我认为您已经找到了最佳解决方案:

from django.db import IntegrityError
from rest_framework.exceptions import ValidationError

class TestSerializer(serializers.ModelSerializer):
def create(self, validated_data):
try:
return super().create(validated_data)
except IntegrityError as error:
raise ValidationError from error

事实上,我找到了一个更好的解决方案,使用自定义异常处理。这个答案中的例子。

最新更新