Обработка ошибок django rest framework
Исключения… позволяют чисто организовать обработку ошибок в центральном или высокоуровневом месте в структуре программы.
‒ Doug Hellmann, Python Exception Handling Techniques
Неприемлемо¶
Подпись: NotAcceptable(detail=None, code=None)
Возникает, когда поступает запрос с заголовком Accept , который не может быть удовлетворен ни одним из доступных рендереров.
Проверка исключений API¶
Существует ряд различных свойств, доступных для проверки состояния исключения API. Вы можете использовать их для создания пользовательской обработки исключений в вашем проекте.
Доступными атрибутами и методами являются:
.detail - Возвращает текстовое описание ошибки.
.get_codes() - Возвращает идентификатор кода ошибки.
.get_full_details() - Возвращает как текстовое описание, так и идентификатор кода.
В большинстве случаев деталь ошибки будет простым элементом:
В случае ошибок валидации деталь ошибки будет представлять собой список или словарь элементов:
Throttled
Raised when an incoming request fails the throttling checks.
By default this exception results in a response with the HTTP status code "429 Too Many Requests".
NotAuthenticated
Raised when an unauthenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the authentication documentation for more details.
Browsability
Because the API chooses the content type of the response based on the client request, it will, by default, return an HTML-formatted representation of the resource when that resource is requested by a web browser. This allows for the API to return a fully web-browsable HTML representation.
Having a web-browsable API is a huge usability win, and makes developing and using your API much easier. It also dramatically lowers the barrier-to-entry for other developers wanting to inspect and work with your API.
See the browsable api topic for more information about the browsable API feature and how to customize it.
NotFound
Сигнатура: NotFound(detail=None, code=None)
Status codes
PermissionDenied
Raised when an authenticated request fails the permission checks.
By default this exception results in a response with the HTTP status code "403 Forbidden".
Adding optional format suffixes to our URLs
Start by adding a format keyword argument to both of the views, like so.
Now update the snippets/urls.py file slightly, to append a set of format_suffix_patterns in addition to the existing URLs.
We don't necessarily need to add these extra url patterns in, but it gives us a simple, clean way of referring to a specific format.
Wrapping API views
REST framework provides two wrappers you can use to write API views.
- The @api_view decorator for working with function based views.
- The APIView class for working with class-based views.
These wrappers provide a few bits of functionality such as making sure you receive Request instances in your view, and adding context to Response objects so that content negotiation can be performed.
The wrappers also provide behaviour such as returning 405 Method Not Allowed responses when appropriate, and handling any ParseError exceptions that occur when accessing request.data with malformed input.
NotAuthenticated
Сигнатура: NotAuthenticated(detail=None, code=None)
Возникает, когда неаутентифицированный запрос не проходит проверку прав доступа.
ParseError
Raised if the request contains malformed data when accessing request.data .
By default this exception results in a response with the HTTP status code "400 Bad Request".
APIException
The base class for all exceptions raised inside an APIView class or @api_view .
To provide a custom exception, subclass APIException and set the .status_code , .default_detail , and default_code attributes on the class.
Inspecting API exceptions
There are a number of different properties available for inspecting the status of an API exception. You can use these to build custom exception handling for your project.
- .detail - Return the textual description of the error.
- .get_codes() - Return the code identifier of the error.
- .get_full_details() - Return both the textual description and the code identifier.
In most cases the error detail will be a simple item:
In the case of validation errors the error detail will be either a list or dictionary of items:
What's next?
In tutorial part 3, we'll start using class-based views, and see how generic views reduce the amount of code we need to write.
Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.
— Doug Hellmann, Python Exception Handling Techniques
AuthenticationFailed¶
Подпись: AuthenticationFailed(detail=None, code=None)
Возникает, когда входящий запрос содержит неправильную аутентификацию.
Дросселированный¶
Подпись: Throttled(wait=None, detail=None, code=None)
Возникает, когда входящий запрос не проходит проверку на дросселирование.
.render()
As with any other TemplateResponse , this method is called to render the serialized data of the response into the final response content. When .render() is called, the response content will be set to the result of calling the .render(data, accepted_media_type, renderer_context) method on the accepted_renderer instance.
You won't typically need to call .render() yourself, as it's handled by Django's standard response cycle.
MethodNotAllowed
Сигнатура: MethodNotAllowed(method, detail=None, code=None)
Возникает при появлении входящего запроса, который не соответствует методу-обработчику представления.
Пользовательская обработка исключений
Чтобы изменить стиль ответа, вы можете написать следующий пользовательский обработчик исключений:
Аргумент context не используется обработчиком по умолчанию, но может быть полезен, если обработчику исключений нужна дополнительная информация, например, обрабатываемое в данный момент представление, доступ к которому можно получить по адресу context[‘view’] .
Обработчик исключений также должен быть настроен в ваших настройках, используя ключ настройки EXCEPTION_HANDLER . Например:
Если параметр ‘ EXCEPTION_HANDLER ‘ не указан, то по умолчанию используется стандартный обработчик исключений, предоставляемый REST-фреймворком:
ParseError
Сигнатура: ParseError(detail=None, code=None)
Возникает, если запрос содержит неправильно сформированные данные при доступе к request.data .
Общие представления ошибок
Используйте их в соответствии с документацией Django по настройке представлений ошибок.
rest_framework.exceptions.server_error
Возвращает ответ с кодом состояния 500 и типом содержимого application/json .
Задается как handler500:
rest_framework.exceptions.bad_request
Возвращает ответ с кодом состояния 400 и типом содержимого application/json .
.renderer_context
A dictionary of additional context information that will be passed to the renderer's .render() method.
Set automatically by the APIView or @api_view immediately before the response is returned from the view.
The Response class extends SimpleTemplateResponse , and all the usual attributes and methods are also available on the response. For example you can set headers on the response in the standard way:
UnsupportedMediaType
Сигнатура: UnsupportedMediaType(media_type, detail=None, code=None)
Возникает, если при обращении к request.data не существует анализаторов, способных обработать тип содержимого данных запроса.
APIException¶
Подпись: APIException()
базовый класс для всех исключений, возникающих внутри класса APIView или @api_view .
Чтобы обеспечить пользовательское исключение, подкласс APIException и установите атрибуты .status_code , .default_detail , и default_code на класс.
.content
The rendered content of the response. The .render() method must have been called before .content can be accessed.
rest_framework.exceptions.server_error ¶
Возвращает ответ с кодом состояния 500 и типом содержимого application/json .
Установить как handler500 :
Response()
The renderers used by the Response class cannot natively handle complex datatypes such as Django model instances, so you need to serialize the data into primitive datatypes before creating the Response object.
You can use REST framework's Serializer classes to perform this data serialization, or use your own custom serialization.
The unrendered, serialized data of the response.
Проверка исключений API
Для проверки состояния исключения API существует ряд различных свойств. Вы можете использовать их для создания пользовательской обработки исключений в вашем проекте.
Доступны следующие атрибуты и методы:
- .detail — Возвращает текстовое описание ошибки.
- .get_codes() — Возвращает идентификатор кода ошибки.
- .get_full_details() — возвращает как текстовое описание, так и идентификатор кода.
В большинстве случаев подробное описание ошибки будет простым элементом:
В случае ошибок валидации деталь ошибки будет представлять собой список или словарь элементов:
Обработка исключений в представлениях фреймворка REST
Представления фреймворка REST обрабатывают различные исключения и возвращают соответствующие ответы на ошибки.
К обрабатываемым исключениям относятся:
В каждом случае фреймворк REST вернет ответ с соответствующим кодом состояния и типом содержимого. Тело ответа будет включать любые дополнительные детали, касающиеся природы ошибки.
Например, следующий запрос:
Может получить ответ об ошибке, указывающий на то, что метод DELETE не разрешен на данном ресурсе:
Ошибки валидации обрабатываются несколько иначе, и в качестве ключей в ответе будут указаны имена полей. Если ошибка валидации не относится к конкретному полю, то в ответе будет использоваться ключ « non_field_errors » или любое строковое значение, установленное для параметра NON_FIELD_ERRORS_KEY .
Пример ошибки валидации может выглядеть следующим образом:
UnsupportedMediaType
Raised if there are no parsers that can handle the content type of the request data when accessing request.data .
By default this exception results in a response with the HTTP status code "415 Unsupported Media Type".
AuthenticationFailed
Raised when an incoming request includes incorrect authentication.
By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the authentication documentation for more details.
ValidationError
The ValidationError exception is slightly different from the other APIException classes:
- The detail argument is mandatory, not optional.
- The detail argument may be a list or dictionary of error details, and may also be a nested data structure. By using a dictionary, you can specify field-level errors while performing object-level validation in the validate() method of a serializer. For example. raise serializers.ValidationError()
- By convention you should import the serializers module and use a fully qualified ValidationError style, in order to differentiate it from Django's built-in validation error. For example. raise serializers.ValidationError('This field must be an integer value.')
The ValidationError class should be used for serializer and field validation, and by validator classes. It is also raised when calling serializer.is_valid with the raise_exception keyword argument:
The generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above.
By default this exception results in a response with the HTTP status code "400 Bad Request".
Django REST Framework provides two error views suitable for providing generic JSON 500 Server Error and 400 Bad Request responses. (Django's default error views provide HTML responses, which may not be appropriate for an API-only application.)
Pulling it all together
Okay, let's go ahead and start using these new components to refactor our views slightly.
Our instance view is an improvement over the previous example. It's a little more concise, and the code now feels very similar to if we were working with the Forms API. We're also using named status codes, which makes the response meanings more obvious.
Here is the view for an individual snippet, in the views.py module.
This should all feel very familiar - it is not a lot different from working with regular Django views.
Notice that we're no longer explicitly tying our requests or responses to a given content type. request.data can handle incoming json requests, but it can also handle other formats. Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us.
Custom exception handling
You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.
In order to alter the style of the response, you could write the following custom exception handler:
The context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as context['view'] .
The exception handler must also be configured in your settings, using the EXCEPTION_HANDLER setting key. For example:
If not specified, the 'EXCEPTION_HANDLER' setting defaults to the standard exception handler provided by REST framework:
APIException
Сигнатура: APIException()
Базовый класс для всех исключений, возникающих внутри класса APIView или @api_view .
Чтобы создать пользовательское исключение, создайте подкласс APIException и установите для него атрибуты .status_code , .default_detail и default_code .
rest_framework.exceptions.server_error
Returns a response with status code 500 and application/json content type.
Set as handler500 :
rest_framework.exceptions.bad_request ¶
Возвращает ответ с кодом состояния 400 и типом содержимого application/json .
Установить как handler400 :
From this point we're going to really start covering the core of REST framework. Let's introduce a couple of essential building blocks.
ValidationError
Сигнатура: ValidationError(detail, code=None)
Исключение ValidationError немного отличается от других классов APIException :
- Аргумент detail является обязательным, а не опциональным.
- Аргумент detail может быть списком или словарем сведений об ошибке, а также может быть вложенной структурой данных. Используя словарь, вы можете указать ошибки на уровне полей при выполнении проверки на уровне объектов в методе validate() сериализатора. Например. raise serializers.ValidationError()
- По соглашению вы должны импортировать модуль serializers и использовать полностью квалифицированный стиль ValidationError , чтобы отличить его от встроенной ошибки валидации Django. Например, raise serializers.ValidationError(‘Это поле должно быть целочисленным значением.’) .
Класс ValidationError следует использовать для валидации сериализаторов и полей, а также классами валидаторов. Он также вызывается при вызове serializer.is_valid с аргументом ключевого слова raise_exception :
NotAcceptable
Raised when an incoming request occurs with an Accept header that cannot be satisfied by any of the available renderers.
By default this exception results in a response with the HTTP status code "406 Not Acceptable".
NotAcceptable
Сигнатура: NotAcceptable(detail=None, code=None)
Возникает при входящем запросе с заголовком Accept, который не может быть удовлетворен ни одним из доступных рендереров.
.template_name
The template_name , if supplied. Only required if HTMLRenderer or some other custom template renderer is the accepted renderer for the response.
.accepted_media_type
The media type that was selected by the content negotiation stage.
Set automatically by the APIView or @api_view immediately before the response is returned from the view.
.status_code
AuthenticationFailed
Сигнатура: AuthenticationFailed(detail=None, code=None)
Возникает, когда входящий запрос содержит неправильную аутентификацию.
Exception handling in REST framework views
REST framework's views handle various exceptions, and deal with returning appropriate error responses.
In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.
Most error responses will include a key detail in the body of the response.
For example, the following request:
Might receive an error response indicating that the DELETE method is not allowed on that resource:
Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the "non_field_errors" key, or whatever string value has been set for the NON_FIELD_ERRORS_KEY setting.
An example validation error might look like this:
How's it looking?
Go ahead and test the API from the command line, as we did in tutorial part 1. Everything is working pretty similarly, although we've got some nicer error handling if we send invalid requests.
We can get a list of all of the snippets, as before.
We can control the format of the response that we get back, either by using the Accept header:
Or by appending a format suffix:
Similarly, we can control the format of the request that we send, using the Content-Type header.
PermissionDenied¶
Подпись: PermissionDenied(detail=None, code=None)
Возникает, когда аутентифицированный запрос не прошел проверку на разрешение.
rest_framework.exceptions.bad_request
Returns a response with status code 400 and application/json content type.
Unless you want to heavily customize REST framework for some reason, you should always use an APIView class or @api_view function for views that return Response objects. Doing so ensures that the view can perform content negotiation and select the appropriate renderer for the response, before it is returned from the view.
PermissionDenied
Сигнатура: PermissionDenied(detail=None, code=None)
Возникает, когда аутентифицированный запрос не прошел проверку на разрешение.
NotFound
By default this exception results in a response with the HTTP status code "404 Not Found".
Throttled
Сигнатура: Throttled(wait=None, detail=None, code=None)
Возникает, когда входящий запрос не проходит проверку на дросселирование.
Руководство API
Request objects
ValidationError¶
Подпись: ValidationError(detail, code=None)
Исключение ValidationError несколько отличается от других классов APIException :
Аргумент detail является обязательным, а не опциональным.
Аргумент detail может представлять собой список или словарь сведений об ошибках, а также может быть вложенной структурой данных. Используя словарь, вы можете указать ошибки на уровне полей при выполнении проверки на уровне объектов в методе validate() сериализатора. Например. raise serializers.ValidationError()
По соглашению вы должны импортировать модуль serializers и использовать полностью квалифицированный стиль ValidationError , чтобы отличить его от встроенной ошибки валидации Django. Например. raise serializers.ValidationError('This field must be an integer value.')
Класс ValidationError следует использовать для сериализатора и валидации полей, а также классами валидаторов. Он также возникает при вызове serializer.is_valid с аргументом ключевого слова raise_exception :
Response objects
REST framework also introduces a Response object, which is a type of TemplateResponse that takes unrendered content and uses content negotiation to determine the correct content type to return to the client.
MethodNotAllowed¶
Подпись: MethodNotAllowed(method, detail=None, code=None)
Возникает, когда происходит входящий запрос, который не сопоставлен с методом-обработчиком на представлении.
Пользовательская обработка исключений¶
Чтобы изменить стиль ответа, вы можете написать следующий пользовательский обработчик исключений:
Аргумент context не используется обработчиком по умолчанию, но может быть полезен, если обработчику исключения нужна дополнительная информация, например, обрабатываемое в данный момент представление, доступ к которому можно получить в виде context['view'] .
Обработчик исключений также должен быть настроен в ваших настройках, используя клавишу настройки EXCEPTION_HANDLER . Например:
Если параметр 'EXCEPTION_HANDLER' не указан, то по умолчанию используется стандартный обработчик исключений, предоставляемый фреймворком REST:
Обработка исключений в представлениях фреймворка REST¶
Представления фреймворка REST обрабатывают различные исключения и возвращают соответствующие ответы на ошибки.
Обрабатываемыми исключениями являются:
Подклассы APIException , поднятые внутри фреймворка REST.
Исключение Django PermissionDenied .
В каждом случае фреймворк REST возвращает ответ с соответствующим кодом состояния и типом содержимого. В теле ответа будут содержаться любые дополнительные сведения о характере ошибки.
Например, следующий запрос:
Может быть получен ответ об ошибке, указывающий на то, что метод DELETE не разрешен на данном ресурсе:
Ошибки валидации обрабатываются несколько иначе, и в качестве ключей в ответе будут указаны имена полей. Если ошибка валидации не относится к конкретному полю, то будет использован ключ «non_field_errors» или любое строковое значение, установленное для параметра NON_FIELD_ERRORS_KEY .
Пример ошибки валидации может выглядеть следующим образом:
NotFound¶
Подпись: NotFound(detail=None, code=None)
MethodNotAllowed
Raised when an incoming request occurs that does not map to a handler method on the view.
By default this exception results in a response with the HTTP status code "405 Method Not Allowed".
UnsupportedMediaType¶
Подпись: UnsupportedMediaType(media_type, detail=None, code=None)
Возникает, если при обращении к request.data нет парсеров, способных обработать тип содержимого данных запроса.
ParseError¶
Подпись: ParseError(detail=None, code=None)
Возникает, если запрос содержит неправильно сформированные данные при доступе к request.data .
NotAuthenticated¶
Подпись: NotAuthenticated(detail=None, code=None)
Возникает, когда неаутентифицированный запрос не прошел проверку на разрешение.
.accepted_renderer
The renderer instance that will be used to render the response.
Set automatically by the APIView or @api_view immediately before the response is returned from the view.
Читайте также: