我正试图强制ValidationError
返回与400不同的状态码。这是我所做的:
class MyValidationError(ValidationError):
status_code = HTTP_403_FORBIDDEN
,然后在序列化程序中:
def validate_field(self, value):
raise MyValidationError
为什么我这里得到400而不是403?有趣的是,如果我使用带有自定义状态代码的PermissionDenied
(我尝试过204)而不是ValidationError
,它将按预期工作。
答案 0 :(得分:3)
Django RestFramework序列化程序将验证所有可能的字段,并最终返回错误集 。
也就是说,假设您期望序列化程序中出现两个验证错误,因为MyValidationError
会引发一个验证错误。在那种情况下,DRF显然会返回HTTP 400
状态代码,因为DRF的设计模式不会引发个人验证错误。
序列化程序验证过程在is_valid()
方法内部完成,并在方法末尾引发ValidationError。
def is_valid(self, raise_exception=False):
....code
....code
if self._errors and raise_exception:
raise ValidationError(self.errors)
return not bool(self._errors)
并且ValidationError
类提出HTTP 400
class ValidationError(APIException):
status_code = status.HTTP_400_BAD_REQUEST
default_detail = _('Invalid input.')
default_code = 'invalid'
.... code
为什么PermissionDenaid返回自定义状态代码?
在is_valid()
(source code)方法中,仅捕获 ValidationError
if not hasattr(self, '_validated_data'):
try:
self._validated_data = self.run_validation(self.initial_data)
except ValidationError as exc:
self._validated_data = {}
self._errors = exc.detail
else:
self._errors = {}
那时,DRF直接引发PermissionDenaid
异常并返回其自己的状态码,该状态码由您自定义
DRF序列化程序ValidationError 绝不会返回除HTTP 400
之外的状态代码,因为它会捕获其他子验证错误例外 (如果有)并且atlast会产生一个主要的ValidationError
,它会根据其设计模式返回HTTP 400
状态代码
参考:
is_valid()
source code
ValidationError
class source code
答案 1 :(得分:0)
yo bruh只需创建您自己的异常类并在序列化器中重新引发它
class ValidationError422(APIException):
status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
class BusinessSerializer(serializers.ModelSerializer):
class Meta:
model = Business
fields = ('id', 'name')
def is_valid(self, raise_exception=False):
try:
return super(BusinessSerializer, self).is_valid(raise_exception)
except ValidationError as e:
raise ValidationError422(detail=e.detail)