Django实现统一包装接口返回值数据格式
前言
最近实在太忙了,开始了一个新的项目,为了快速形成产品,我选择了Django来实现后端,然后又拿起了之前我封装了项目脚手架「DjangoStarter」。
由于前段时间我写了不少.NetCore的后端代码,对CRUD的接口开发又有了一些新的理解,所以肯定也要把DjangoStarter改造一番,改得更加顺手~
题外话:话说我在前端终于真正用上react,不得不说 ts + react 真好用,「前端带师」的安利可真不错啊(妙啊
正题
准确来讲是搭配DjangoRestFramework来实现的,核心代码分为两部分,一个是错误处理包装,一个是响应包装renderer。
无论请求是否报错,都会被我们自定义的renderer包装。
代码
开始上代码吧~
首先在项目里添加一个新的Python包,位置根据情况自行安排,我在DjangoStarter模板中的位置是utils/response,接下来的两个文件都会放在这个目录中
第一个是错误处理的exception.py文件代码
from typing import Dict
from rest_framework.exceptions import ValidationError
from rest_framework.views import exception_handler
from rest_framework.views import Response
from rest_framework.utils.serializer_helpers import ReturnDict
from rest_framework import status
def custom_handler(err: ValidationError, context: dict):
# 先调用REST framework默认的异常处理方法获得标准错误响应对象
response: Response = exception_handler(err, context)
if response is None:
return Response({
'message': f'服务器错误:{err}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
else:
res = {'message': response.reason_phrase}
res.update(response.data)
return Response(res, status=response.status_code, exception=True)
然后是自定义renderer.py代码:
from rest_framework.renderers import JSONRenderer
class CustomRenderer(JSONRenderer):
# 重构render方法
def render(self, data, accepted_media_type=None, renderer_context=None):
if renderer_context:
# 响应的信息,成功和错误的都是这个
# 成功和异常响应的信息,异常信息在前面自定义异常处理中已经处理为{'message': 'error'}这种格式
# 如果返回的data为字典
if isinstance(data, dict):
# 响应信息中有message和code这两个key,则获取响应信息中的message和code,并且将原本data中的这两个key删除,放在自定义响应信息里
# 响应信息中没有则将msg内容改为请求成功 code改为请求的状态码
msg = data.pop('message', '请求成功')
code = data.pop('code', renderer_context["response"].status_code)
# 如果不是字典则将msg内容改为请求成功 code改为响应的状态码
else:
msg = '请求成功'
code = renderer_context["response"].status_code
# 自定义返回的格式
ret = {
'message': 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)
关键的地方都注释了,很容易看懂
包装出来每个接口的返回值就都是这个样子
{
"message": "msg",
"code": 200,
"data": {
"data1": "123"
}
}
配置
为了让上面的代码发挥作用,还得配置一下RestFramework
编辑settings.py文件,在REST_FRAMEWORK节点添加这两个配置,注意路径要和前面两个文件的路径一致。这里我是以DjangoStarter项目为例。
REST_FRAMEWORK = {
# 全局配置异常模块
'EXCEPTION_HANDLER': 'utils.response.exception.custom_handler',
# 修改默认返回JSON的renderer的类
'DEFAULT_RENDERER_CLASSES': ('utils.response.renderer.CustomRenderer',),
}
现在就完成了~ 就是这么简单。
(比AspNetCore包装返回值简单……)
完整代码可以在GitHub上查看:https://github.com/Deali-Axy/DjangoStarter
参考资料
- Django rest framework自定义返回数据格式:https://blog.csdn.net/qq_41475058/article/details/112676908
Django实现统一包装接口返回值数据格式的更多相关文章
- django学习-17.如何提供一个规范的接口返回值
目录结构 1.前言 2.进行实际的一个完整流程操作 2.1.第一步:编写一个用于查询用户数据的视图函数 2.2.第二步:编写对应的一个url匹配规则 2.3.第三步:启动django项目[hellow ...
- C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解 ...
- WebApi 接口返回值类型详解 ( 转 )
使用过Webapi的园友应该都知道,Webapi的接口返回值主要有四种类型 void无返回值 IHttpActionResult HttpResponseMessage 自定义类型 此篇就围绕这四块分 ...
- WebApi接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.作为程序猿,我们都知道参数和返回值是编程领域不可分割的两大块,此前分享了 ...
- Asp.Net WebApi接口返回值IHttpActionResult
WebApi是微软在VS2012 MVC4版本中绑定发行的,webapi2.0同mvc5发行的 webapi一共有以下接口返回值 1.void无返回值2.IHttpActionResult Json( ...
- WebApi 接口返回值不困惑:返回值类型详解。IHttpActionResult、void、HttpResponseMessage、自定义类型
首先声明,我还没有这么强大的功底,只是感觉博主写的很好,就做了一个复制,请别因为这个鄙视我,博主网址:http://www.cnblogs.com/landeanfen/p/5501487.html ...
- (转)C# WebApi 接口返回值不困惑:返回值类型详解
原文地址:http://www.cnblogs.com/landeanfen/p/5501487.html 正文 前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi ...
- [转]C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
本文转自:http://www.cnblogs.com/landeanfen/p/5501487.html 阅读目录 一.void无返回值 二.IHttpActionResult 1.Json(T c ...
- 只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常
## 统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生. 比较通用的返回值格式如下: ```jav ...
随机推荐
- 微信小程序断网处理
wx.onNetworkStatusChange(function callback) 参数 function callback 网络状态变化事件的回调函数 参数 Object res 属性 类型 说 ...
- PhpStorm中绘画UML
IDE支持 在Plugins中 安装PlantUML integration插件 到http://www.graphviz.org/网站下载graphviz.exe并安装(这个软件可以支持更多的UML ...
- OCCT基础
基础 构成总览 Root类 基本类型,如布尔,字符,整数或实数 安全处理动态创建的对象,确保自动删除未引用的对象 可配置的内存管理器,提高了应用程序的性能 包含运行时类型信息机制,有助于创建复杂应用 ...
- source insight新建工程
1.打开Source Insight.如果已经打开过项目,则选择Project->Close Project.然后点击Project->New Project: 2.在弹出界面填入项目名 ...
- fastcgi未授权访问及任意命令执行
1. 漏洞原理 服务端使用fastcgi协议并对外网开放9000端口,攻击者可以构造fastcgi协议包内容,实现未授权访问服务端.php文件以及执行任意命令. 2. 漏洞利用 第一步 搭建vulhu ...
- 西门子S210电机位置控制过调问题解决方法
问题描述 创建完工艺对象,使用MC_MoveAbsolute工艺指令进行绝对定位,发现在下达指令后,电机会出现先超过目标位置再回调的现象,即过冲. 电机连接的机械结构为旋转轴,而不是线性轴. 解决方法 ...
- python -sorted 学习
跟C++ STL中的sort的用法类似,sorted用来对列表进行排序 比如: list = [3,4,82,66,22,11] 用sorted(list),就会对对list这个表进行排序 如果,so ...
- SpringMVC源码解读 - RequestMapping注解实现解读
SpringMVC源码解读 - RequestMapping注解实现解读 - RequestCondition体系 https://www.cnblogs.com/leftthen/p/520840 ...
- SpringDataRedis的Keyspaces设置
前言 原文:https://docs.spring.io/spring-data/redis/docs/2.3.2.RELEASE/reference/html/#redis.repositories ...
- 一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 MySQL 数据库,又插入了一条数据,此时 id 是几?如何获取当前数据库版本?
一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 MySQL 数据库,又插入了一条数据,此时 id 是几? 一般情况下,我们创建的表的类型是InnoDB,如果新增一条记录(不重启mysq ...