Создание пользовательских Exceptions в Django
Ошибки сериализации, возвращаемые Django Rest Framework, не так просто отображать во внешнем интерфейсе. Вот как он возвращает ошибки сериализации для распространенных ошибок регистрации пользователей:
{'username': ['This field is required.'], 'password': ['This field must be at least 8 chars'], 'email': ['This field cannot be blank']}
Пользовательскому интерфейсу трудно с этим справиться. Возможно, придется проделать большую работу, чтобы определить, к какому полю относится сообщение об ошибке. Интерфейсу также сложно анализировать кучу массивов на наличие ошибок.
Понятные сообщения об ошибках
Чтобы сделать сообщения об ошибках более понятными:
Во-первых, переопределите сообщения об ошибках по умолчанию в __init__
методе вашего сериализатора. Здесь меняем его так, чтобы он действительно говорил, с каким полем (то есть с именем пользователя вместо «Это поле») связана ошибка:
class UserSerializer(serializers.ModelSerializer): email = serializers.EmailField(required=True) username = serializers.CharField(required=True) password = serializers.CharField(min_length=8, required=True) class Meta: model = User fields = ("id", "username", "email", "password") def __init__(self, *args, **kwargs): super(UserSerializer, self).__init__(*args, **kwargs) self.fields["username"].error_messages["required"] = u"username is required" self.fields["username"].error_messages["blank"] = u"username cannot be blank" self.fields["email"].error_messages["required"] = u"email is required" self.fields["email"].error_messages["blank"] = u"email cannot be blank" self.fields["password"].error_messages[ "min_length" ] = u"password must be at least 8 chars"
Определение пользовательского исключения(Exception)
В нашем новом файле с именем. exceptions.py мы
просматриваем поля, в которых могли бы переопределить ошибку, и получить первый элемент в массиве.
Если для каждого поля есть несколько исключений, нас это не беспокоит, потому что, если пользователь исправит одно, он перейдет к следующему исключению.
from rest_framework.exceptions import ValidationError from rest_framework.views import exception_handler def base_exception_handler(exc, context): response = exception_handler(exc, context) # check that a ValidationError exception is raised if isinstance(exc, ValidationError): # here prepare the 'custom_error_response' and # set the custom response data on response object if response.data.get("username", None): response.data = response.data["username"][0] elif response.data.get("email", None): response.data = response.data["email"][0] elif response.data.get("password", None): response.data = response.data["password"][0] return response
Наконец, убедитесь, что вы указали settings.py
, что используете новый обработчик исключений :
REST_FRAMEWORK = { "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), "DEFAULT_AUTHENTICATION_CLASSES": ( "rest_framework.authentication.TokenAuthentication", "rest_framework.authentication.SessionAuthentication", "rest_framework.authentication.BasicAuthentication", ), "EXCEPTION_HANDLER": ("app.exceptions.base_exception_handler"), }
Вот более понятное сообщение об ошибке!
Вывод
Пользовательские исключения с использованием Django Rest Framework полезны, в тех случаях, когда нам нужно отдать в пользовательский интерфейс более понятное сообщение об ошибках. Спасибо за прочтение.