例外-Django REST框架
exceptions.py
例外
例外…允许错误处理干净地组织在程序结构中的中央或高级位置。
-道格·赫尔曼Python异常处理技术
REST框架视图中的异常处理
REST框架的视图处理各种异常,并处理返回适当的错误响应。
处理的例外情况如下:
- 子类
APIException
在REST框架内提升。 - 姜戈氏
Http404
例外。 - 姜戈氏
传教
例外。
在每种情况下,REST框架都将返回一个具有适当状态代码和内容类型的响应。响应的主体将包括关于错误性质的任何其他细节。
大多数错误响应将包括一个键。detail
在回应的主体中。
例如,以下请求:
DELETE http://api.example.com/foo/bar HTTP/1.1
Accept: application/json
可能会收到错误响应,指示DELETE
方法不允许在该资源上使用:
HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 42
{"detail": "Method 'DELETE' not allowed."}
验证错误的处理方式略有不同,并且将字段名作为响应中的键。如果验证错误不特定于特定字段,那么它将使用“non_field_error”键,或者为NON_FIELD_ERRORS_KEY
背景。
任何示例验证错误都可能如下所示:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 94
{"amount": ["A valid integer is required."], "description": ["This field may not be blank."]}
自定义异常处理
您可以通过创建一个处理程序函数来实现自定义异常处理,该函数将API视图中引发的异常转换为响应对象。这允许您控制API使用的错误响应的样式。
函数必须使用一对参数,第一个参数是要处理的异常,第二个参数是包含任何额外上下文的字典,比如当前正在处理的视图。异常处理程序函数应该返回Response
对象,或返回None
如果无法处理异常。如果处理程序返回None
然后将重新引发异常,Django将返回一个标准的HTTP 500“服务器错误”响应。
例如,您可能希望确保所有错误响应都包括响应正文中的HTTP状态代码,如下所示:
HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 62
{"status_code": 405, "detail": "Method 'DELETE' not allowed."}
为了更改响应的样式,可以编写以下自定义异常处理程序:
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
# Now add the HTTP status code to the response.
if response is not None:
response.data['status_code'] = response.status_code
return response
默认处理程序不使用上下文参数,但如果异常处理程序需要更多信息(例如当前正在处理的视图),则可以将其访问为context['view']
.
异常处理程序还必须在您的设置中配置,使用EXCEPTION_HANDLER
设置钥匙。例如:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}
如果未指定,则'EXCEPTION_HANDLER'
将默认值设置为REST框架提供的标准异常处理程序:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}
请注意,异常处理程序将只为引发的异常生成的响应调用。它将不用于视图直接返回的任何响应,例如HTTP_400_BAD_REQUEST
当序列化程序验证失败时,泛型视图返回的响应。
API参考
APIException
签署: APIException()
这个基类中引发的所有异常APIView
类或@api_view
.
若要提供自定义异常,请将APIException
并设置.status_code
, .default_detail
,和default_code
类的属性。
例如,如果您的API依赖于有时无法访问的第三方服务,您可能希望为“503 Service不可用”HTTP响应代码实现异常。你可以这样做:
from rest_framework.exceptions import APIException
class ServiceUnavailable(APIException):
status_code = 503
default_detail = 'Service temporarily unavailable, try again later.'
default_code = 'service_unavailable'
检查API异常
有许多不同的属性可用于检查API异常的状态。您可以使用这些来为项目构建自定义异常处理。
可用的属性和方法是:
-
.detail
-返回错误的文本描述。 -
.get_codes()
-返回错误的代码标识符。 -
.get_full_details()
-返回文本描述和代码标识符。
在大多数情况下,错误细节将是一个简单的项目:
>>> print(exc.detail)
You do not have permission to perform this action.
>>> print(exc.get_codes())
permission_denied
>>> print(exc.get_full_details())
{'message':'You do not have permission to perform this action.','code':'permission_denied'}
在出现验证错误的情况下,错误详细信息将是项的列表或字典:
>>> print(exc.detail)
{"name":"This field is required.","age":"A valid integer is required."}
>>> print(exc.get_codes())
{"name":"required","age":"invalid"}
>>> print(exc.get_full_details())
{"name":{"message":"This field is required.","code":"required"},"age":{"message":"A valid integer is required.","code":"invalid"}}
ParseError
签署: ParseError(detail=None, code=None)
如果请求在访问时包含格式错误的数据,则引发request.data
.
默认情况下,此异常将导致HTTP状态代码“400坏请求”的响应。
认证失败
签署: AuthenticationFailed(detail=None, code=None)
当传入请求包含不正确的身份验证时引发。
默认情况下,此异常将导致HTTP状态代码“401未经身份验证”的响应,但根据所使用的身份验证方案,它也可能导致“403禁止”响应。见认证文件更多细节。
未认证
签署: NotAuthenticated(detail=None, code=None)
当未经身份验证的请求无法通过权限检查时引发。
默认情况下,此异常将导致HTTP状态代码“401未经身份验证”的响应,但根据所使用的身份验证方案,它也可能导致“403禁止”响应。见认证文件更多细节。
传教
签署: PermissionDenied(detail=None, code=None)
当通过身份验证的请求无法通过权限检查时引发。
默认情况下,此异常将导致HTTP状态代码“403 For禁忌”的响应。
诺顿
签署: NotFound(detail=None, code=None)
在给定URL处不存在资源时引发。此异常等效于标准Http404
Django例外
默认情况下,此异常将导致HTTP状态代码“404 Notfind”的响应。
方法不准备
签署: MethodNotAllowed(method, detail=None, code=None)
当未映射到视图上的处理程序方法的传入请求发生时引发。
默认情况下,此异常将导致HTTP状态代码“405方法不允许”的响应。
NotAcceptable
签署: NotAcceptable(detail=None, code=None)
对象发生传入请求时引发Accept
任何可用呈现器无法满足的标头。
默认情况下,此异常将导致HTTP状态代码“406不可接受”的响应。
非支持媒体类型
签署: UnsupportedMediaType(media_type, detail=None, code=None)
如果在访问时没有能够处理请求数据的内容类型的解析器,则引发request.data
.
默认情况下,此异常将导致HTTP状态代码“415不支持的媒体类型”的响应。
节流
签署: Throttled(wait=None, detail=None, code=None)
当传入请求无法通过节流检查时引发。
默认情况下,此异常会导致HTTP状态代码“429太多请求”的响应。
验证错误
签署: ValidationError(detail, code=None)
这个验证错误
异常与另一个略有不同。APIException
课程:
- 这个
detail
参数是强制性的,不是可选的。 - 这个
detail
参数可以是错误详细信息的列表或字典,也可以是嵌套的数据结构。 - 按照约定,您应该导入序列化程序模块并使用完全限定的
验证错误
样式,以区别于Django的内置验证错误。例如。raise serializers.ValidationError('This field must be an integer value.')
这个验证错误
类应用于序列化程序和字段验证,并由验证器类使用。调用时也会引发serializer.is_valid
带着raise_exception
关键词参数:
serializer.is_valid(raise_exception=True)
泛型视图使用raise_exception=True
标志,这意味着您可以覆盖API中全局验证错误响应的样式。为此,请使用自定义异常处理程序,如前所述。
默认情况下,此异常将导致HTTP状态代码“400坏请求”的响应。
泛型错误视图
Django REST框架提供了两个适合于提供通用JSON的错误视图500
服务器错误和400
请求回应不佳。(Django的默认错误视图提供HTML响应,这可能不适合仅用于API的应用程序。)
按以下方式使用Django的自定义错误视图文档.
rest_framework.exceptions.server_error
返回状态代码的响应。500
和application/json
内容类型
设为handler500
:
handler500 = 'rest_framework.exceptions.server_error'
rest_framework.exceptions.bad_request
返回状态代码的响应。400
和application/json
内容类型
设为handler400
:
handler400 = 'rest_framework.exceptions.bad_request'