Wrapping Django API Responses in a Unified Format
Introduction I've been really busy lately. I started a new project, and to get a product out quickly I chose Django for the backend, then picked up the project scaffolding I had packaged before, DjangoStarter. Because I wrote quite a bit of .NetCore backend code recently and gained some new insights into CRUD API development, I definitely have to revamp DjangoStarter as well, to make it more convenient to use~ Side note: I finally actually started using react on the frontend. I have to say ts + react is really nice to use,
目录5 个章节
Introduction
I've been really busy lately. I started a new project, and to get a product out quickly I chose Django for the backend, then picked up the project scaffolding I had packaged before, DjangoStarter.
Because I wrote quite a bit of .NetCore backend code recently and gained some new insights into CRUD API development, I definitely have to revamp DjangoStarter as well, to make it more convenient to use~
Side note: I finally actually started using react on the frontend. I have to say ts + react is really nice to use. The recommendation from "Frontend Guru" was really solid (nice
The Main Topic
To be precise, this is implemented together with DjangoRestFramework. The core code consists of two parts: one is the error-handling wrapper, and the other is the response wrapper renderer.
Whether the request errors or not, it will be wrapped by our custom renderer.
Code
Let's get to the code~
First, add a new Python package to the project. Place it wherever makes sense for you; in the DjangoStarter template, I put it at utils/response. The next two files will both go in this directory.
The first is the error-handling exception.py file:
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:
# 因为RestFramework默认的报错信息是 detail 字段,这里取出系统的报错信息
msg = response.data.pop('detail', response.reason_phrase)
res = {'message': msg}
res.update(response.data)
return Response(res, status=response.status_code, exception=True)
Then the custom renderer.py code:
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)
The key parts are commented, so it should be easy to follow.
After wrapping, every API's return value looks like this:
{
"message": "msg",
"code": 200,
"data": {
"data1": "123"
}
}
Configuration
For the code above to take effect, you still need to configure RestFramework.
Edit the settings.py file and add these two settings under the REST_FRAMEWORK node. Make sure the paths match the two files above. Here I'm using the DjangoStarter project as an example.
REST_FRAMEWORK = {
# 全局配置异常模块
'EXCEPTION_HANDLER': 'utils.response.exception.custom_handler',
# 修改默认返回JSON的renderer的类
'DEFAULT_RENDERER_CLASSES': ('utils.response.renderer.CustomRenderer',),
}
That's it~ It's that simple.
(Simpler than wrapping return values in AspNetCore……)
The full code is available on GitHub: https://github.com/Deali-Axy/DjangoStarter
References
- Customizing Django REST framework response data format: https://blog.csdn.net/qq_41475058/article/details/112676908
_EOF_
Wrapping Django API Responses in a Unified Format
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
Django全文检索实现:HayStack-+-Whoosh-+-Jieba
涉及到的工具 haystack是django的开源搜索框架,该框架支持**Solr**, Elasticsearch, Whoosh, **Xapian搜索引擎,不用更改代码,直接切换引擎,减少代码量。 搜索引擎使用Whoosh,这是一个由纯Python实现的全文搜索引擎,没有二进制文件等,比较小巧,配置比较简单,当然性能自然略低。 中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分
2022-08-26 · Django · 约 1 分钟
关于uwsgi服务器的管理
前言 使用Django开发项目好是好,就是部署的时候太麻烦,使用Uwsgi服务器的话,每次修改了代码,都需要重新启动服务器才可以生效。然后uwsgi服务器的重启也挺麻烦。 看了一下官网的文档,最好是把uwsgi安装到venv虚拟环境里面,这样的话在 ps aux 的时候容易区分啦。 查看uwsgi进程 ps -aux | grep uwsgi 结束原uwsgi进程 kill -9 27543 结论
2025-10-27 · Django · 约 1 分钟
Django过时了吗?从ASGI到AI时代的思考
Django过时?技术趋势变了而已,异步支持短板在AI时代更明显。生态工程化再稳,也挡不住轻量框架和ASGI的冲击。独立开发者该考虑新选择了?
2025-09-12 · Django · 约 1 分钟
Django应用部署:uwsgi+Nginx方式
环境准备 nginx+uwsgi方式部署顾名思义,需要nginx和uwsgi两个软件包。 nginx不用说,是必备的,关于nginx的安装本文不再赘述,详情可以自行搜索或者参考我以前的文章: Debian8搭建LEMP环境 安装uwsgi pip install uwsgi 上传项目代码 & 测试 # 进入项目目录,具体目录请自行选择 cd /path/to/project # 建立虚拟环境 v
2022-04-02 · Django · 约 1 分钟
讨论
共 0 条加载评论中…