• 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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    第二个: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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    当然,在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',
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

  • 相关阅读:
    一篇快速教你如何创建专业级数据可视化库
    运维团队如何加强安全设备监控与日志管理
    异步FIFO设计的仿真与综合技术(6)
    Linux系统编程——文件的写入及读取
    中英文说明书丨艾美捷无内毒素卵清蛋白参数和应用
    构建一个语音转文字的WebApi服务
    恭喜顺利结项 | 开源之夏 2023openGauss项目结项结果公示
    Web系统常见安全漏洞介绍及解决方案-CSRF攻击
    【C语言 | 指针】指针和数组关系——剪不断,理还乱
    【vue】视频播放器video.js插件使用:
  • 原文地址:https://blog.csdn.net/weixin_39168138/article/details/134479493