В Django REST Framework, почему повышение serializers.ValidationError возвращает ошибки в разном формате в методах validate() и create()?
Я работаю над проектом DRF и имею сериализатор следующего вида:
class SomeSerializer(serializers.Serializer):
number_field = serializers.IntegerField(required=False, min_value=25, max_value=100)
В моем файле settings.py у меня есть
REST_FRAMEWORK = {
other settings....
'EXCEPTION_HANDLER': 'apps.utils.exceptions.custom_exception_handler',
}
В пользовательском обработчике исключений я обрабатываю ValidationError следующим образом:
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first
response = exception_handler(exc, context)
messages = None
code = None
detail = None
if response is not None:
# Map specific exceptions to custom error codes
if isinstance(exc, ValidationError):
code = "validation_error"
detail = "One or more fields failed validation."
messages = exc.detail
status_code = status.HTTP_400_BAD_REQUEST
# After checking for other errors here in between
else:
code = "unexpected_error"
detail = response.data.get("detail", "An unexpected error occurred.")
messages = response.data.get("messages", {"error": str(exc)})
"""
In between the if and else, AuthenticationFailed, PermissionDenied, NotFound, are handled. Add an appropriate code and return in the format
response.data = {
"detail": detail,
"code": code,
"messages": messages
}
"""
Пользовательский обработчик исключений настроен на возврат ошибки в формате, показанном ниже. Но это происходит, только если я проверяю диапазон min и max внутри метода create() (без min_value и max_value, определенных в самом поле сериализатора)
{
"detail": "One or more fields failed validation.",
"code": "validation_error",
"messages": {
"number_field": [
"Ensure this value is greater than or equal to 25."
]
}
}
Но если я оставлю проверку на min_value и max_value, указанные в поле сериализатора, или даже если я вручную проверю его внутри метода validate или метода validate_number_field, он возвращается в оригинальном формате DRF
{
"number_field": [
"Ensure this value is greater than or equal to 25."
]
}
Один из способов получить формат ошибки из пользовательского обработчика исключений с min_value и max_value, определенными для поля сериализатора, заключался в переопределении метода to_internal_value и обработке ValidationError там.
def to_internal_value(self, data):
try:
return super().to_internal_value(data)
except serializers.ValidationError as exc:
raise serializers.ValidationError({
"detail": "One or more fields failed validation.",
"code": "validation_error",
"messages": exc.detail
})
Но для меня это лишает смысла наличие пользовательского обработчика исключений. Если я хочу, чтобы такое поведение было характерно для всего проекта, какие у меня есть варианты, кроме подкласса serializers.Serializer (или ModelSerializer) и переопределения метода to_internal_value.