自定义Response返回信息,但那个只用于正确的返回success,但是当我们用到了权限
auth 401、方法不允许method 405,等等,这时候我们就用自己自定义异常返回信息
1、定义settings配置文件
#定义异常返回的路径脚本位置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'common.utils.custom_execption.custom_exception_handler',
}
2、定义脚本
#注意,脚本路径需要与settings.py 定义的一样
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:
print(response.data)
response.data.clear()
response.data['code'] = response.status_code
response.data['data'] = []
if response.status_code == 404:
try:
response.data['message'] = response.data.pop('detail')
response.data['message'] = "Not found"
except KeyError:
response.data['message'] = "Not found"
if response.status_code == 400:
response.data['message'] = 'Input error'
elif response.status_code == 401:
response.data['message'] = "Auth failed"
elif response.status_code >= 500:
response.data['message'] = "Internal service errors"
elif response.status_code == 403:
response.data['message'] = "Access denied"
elif response.status_code == 405:
response.data['message'] = 'Request method error'
return response
#无需调用,报错的时候他自己会调用!!
实践中我们的自定义的响应为:
要求我们 返回的值必须为json串,包含message,code, data, result
{
"message": "success",
"code": "OK",
"data": null,
"result": true
}
# -*- coding: utf-8 -*-
import traceback
from django.core.exceptions import PermissionDenied
from rest_framework import status
from rest_framework.compat import set_rollback
from rest_framework.response import Response
from rest_framework.exceptions import (AuthenticationFailed, MethodNotAllowed, NotAuthenticated,
PermissionDenied as RestPermissionDenied,
ValidationError)
from django.http import Http404
from component.constants import ResponseCodeStatus
from common.log import logger
def exception_handler(exc, content):
data = {
'result': False,
'data': None
}
if isinstance(exc, (NotAuthenticated, AuthenticationFailed)):
data = {
'result': False,
'code': ResponseCodeStatus.UNAUTHORIZED,
'detail': u'用户未登录或登录态失效,请使用登录链接重新登录',
'login_url': ''
}
return Response(data, status=status.HTTP_403_FORBIDDEN)
if isinstance(exc, PermissionDenied) or isinstance(exc, RestPermissionDenied):
message = exc.detail if hasattr(exc, 'detail') else u'该用户没有该权限功能'
data = {
'result': False,
'code': ResponseCodeStatus.PERMISSION_DENIED,
'message': message
}
return Response(data, status=status.HTTP_403_FORBIDDEN)
else:
if isinstance(exc, ValidationError):
data.update({
'code': ResponseCodeStatus.VALIDATE_ERROR,
'message': exc.detail
})
elif isinstance(exc, MethodNotAllowed):
data.update({
'code': ResponseCodeStatus.METHOD_NOT_ALLOWED,
'message': exc.detail,
})
elif isinstance(exc, Http404):
# 更改返回的状态为为自定义错误类型的状态码
data.update({
'code': ResponseCodeStatus.OBJECT_NOT_EXIST,
'message': exc.message,
})
else:
# 调试模式
logger.error(traceback.format_exc())
print traceback.format_exc()
# if settings.RUN_MODE != 'PRODUCT':
# raise exc
# 正式环境,屏蔽500
data.update({
'code': ResponseCodeStatus.SERVER_500_ERROR,
'message': exc.message,
})
set_rollback()
return Response(data, status=status.HTTP_200_OK)
#这里是字段的 校验
def validate_fields(data, *fields):
"""校验必填参数"""
validations = []
for field in fields:
if field not in data:
validations.append(u'%s该字段是必填项' % field)
if validations:
raise ValidationError(validations)