DRF统一返回格式

DRF中如何统一返回格式

目前在在给科室网站定义DRF的时候,遇到这样的一个问题,就是DRF的原生返回的式样是多样的,例如在访问成功的时候会返回这样的数据{“access”:fkasjfkljgkljgklsjgksjlksjfkljslfjs},但是在序列化器错误的时候,会返回类似这样的格式{‘username’: [ErrorDetail(string=‘该字段是必填项。’, code=‘required’)], ‘password’: [ErrorDetail(string=‘该字段是必填项。’, code=‘required’)]},但是另外的接口访问的时候禁止,会出现这样的形式{‘detail’: ErrorDetail(string=‘找不到指定凭据对应的有效用户’, code=‘no_active_account’)},为了可以让前端可以方便查看相关的信息,我需要将这样不同的返回统一为{‘msg’:xxx,‘code’:200,‘data’:xxx}的式样,其中涉及到两个关键的文件,一个是自定义错误处理,另外一个是关于返回前端的数据渲染,分别是以下的两个文件:
1、customException.py:

from rest_framework.views import exception_handler
from rest_framework.views import Response
from rest_framework import status
from zzer_website2 import settings


def custom_handler(err,context: dict):
    # 先调用REST framework默认的异常处理方法获得标准错误响应对象
    response: Response = exception_handler(err, context)
    if response is None:
        # 在DEBUG模式下不处理系统异常,如果处理后错误页面将变成标准格式
        if settings.DEBUG:
            raise err
        res = {'msg': '服务器错误!','code':500,'data':err}
        return Response(res, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True) #只有500这个状态码
    else:
        msg = response.reason_phrase
        if "detail" in response.data:
            data = response.data["detail"]
        else:
            data=[]
            for k,v in response.data.items():
                if isinstance(v,list):
                    data.append(k+v[0])
        res = {}
        res.update(response.data)
        res["msg"] = msg
        res["code"] = response.status_code
        res['data']=data
        return Response(res, status=response.status_code, exception=True)

第二个:customrender.py,如下

from rest_framework.renderers import JSONRenderer

# 导入控制返回的JSON格式的类
class CustomRenderer(JSONRenderer):
    def render(self, data, accepted_media_type=None, renderer_context=None):
        if renderer_context:
            # 判断实例的类型,返回的数据可能是列表也可能是字典
            if isinstance(data, dict):
                # 如果是字典的话应该是返回的数据,会包含 msg, code, status 等字段,必须抽离出来
                msg = data.pop('msg', 'success')
                code = renderer_context['response'].status_code

                if data.get('data',None):
                    data=data.pop('data')

            # 自定义返回数据格式
            ret = {
                'msg': msg,
                'code': code,
                'data': data,
            }

            # 返回 JSON 数据
            return super().render(ret, accepted_media_type, renderer_context)
        else:
            return super().render(data, accepted_media_type, renderer_context)

当然,在setting也需要配置好指定相关的DRF配置,如下:

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 15,
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 使用rest_framework_simplejwt验证身份
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication'
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'backend.utils.CustomRender.CustomRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
    'EXCEPTION_HANDLER': 'backend.utils.CustomException.custom_handler',
}

这样的话,就可以统一后端返回的数据,前端的话,只需要都从response[‘data’]中取到相关信息就行显示就足够了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值