自定义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)