django rest framework 自定义异常返回 包含message,code, data, result

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

你可能感兴趣的:(django)