Django的restframework接口框架自定义返回数据格式的示例详解
作者:xiejava1018 发布时间:2023-06-13 05:13:51
在前后端分离是大趋势的背景下,前端获取数据都是通过调用后台的接口来获取数据微服务的应用越来越多。Django是Python进行web应用开发常用的web框架,用Django框架进行web应用框架减少了很多工作,通常用很少量的代码就可以实现数据的增、删、改、查的业务应用,同样用Django的restframework的框架对外发布接口也是非常的简单方便,几行代码就可以将数据对象通过接口的方式提供服务。因为在实际开发过程中接口的返回数据有一定的格式,本文介绍通过自定义Response返回对象来自定义接口返回数据格式。
以下示例将数据对象Friend通过restframework框架进行接口发布。
只要定义Friend数据对象
class Friend(BaseModel):
id=models.AutoField(primary_key=True)
siteName=models.CharField(max_length=20, verbose_name='友链站点名称')
path=models.CharField(max_length=100, verbose_name='地址路径')
desc=models.CharField(max_length=200, verbose_name='描述')
def __str__(self):
return self.siteName
class Meta:
verbose_name='友链'
verbose_name_plural='友链'
定义一个序列化类将返回的字段序列化
class FriendModelSerializer(serializers.ModelSerializer):
class Meta:
model = Friend
fields = "__all__"
定义一个接口视图类获取数据
class FriendView(viewsets.ModelViewSet):
queryset = Friend.objects.all()
serializer_class = FriendModelSerializer
定义接口路由就可以通过httprestfull的接口进行访问了
friend_list=views.FriendView.as_view({'get':'list',})
urlpatterns = [
path('friend/',friend_list),
]
接口访问效果如下:
http://localhost:8000/api/friend/
但是在项目中经常会碰到接口格式变化的情况,restframework框架默认的返回数据格式不满足应用的需求。比如一般的接口都会有接口返回的code、msg、data,code用来标识接口返回代码比如200是正常,msg用来记录异常或其信息,data用来返回具体的数据。
通过restframework接口自定义返回数据格式也是很简单方便的。
先自定义Response返回对象,在返回对象中自定义数据返回的格式,示例代码如下:
from rest_framework.response import Response
from rest_framework.serializers import Serializer
class CustomResponse(Response):
def __init__(self,data=None,code=None,msg=None,
status=None,
template_name=None, headers=None,
exception=False, content_type=None,**kwargs):
super().__init__(None, status=status)
if isinstance(data, Serializer):
msg = (
'You passed a Serializer instance as data, but '
'probably meant to pass serialized `.data` or '
'`.error`. representation.'
)
raise AssertionError(msg)
#自定义返回格式
self.data={'code':code,'msg':msg,'data':data}
self.data.update(kwargs)
self.template_name=template_name
self.exception=exception
self.content_type=content_type
if headers:
for name, value in headers.items():
self[name] = value
在接口接口视图类获取数据返回时,使用该自定义的Response返回对象。
class FriendView(viewsets.ModelViewSet):
queryset = Friend.objects.all()
serializer_class = FriendModelSerializer
#自定义list方法,自定义Response返回
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return CustomResponse(data=serializer.data, code=200, msg="OK", status=status.HTTP_200_OK)
接口访问效果如下:
可以看到返回数据格式中增加了code,msg 数据放到了data节点
列表数据通常接口要提供翻页功能,在接口中要有总页数、当前页、是否有下一页的信息。
可以自定义一个分页器,在分页器中自定义需要返回的分页参数
参考示例代码如下:
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from common.customresponse import CustomResponse
class MyPage(PageNumberPagination):
page_size = 8 #每页显示数量
max_page_size = 50 #每页最大显示数量。
page_size_query_param = 'size' #每页数量的参数名称
page_query_param = 'page' #页码的参数名称
def get_paginated_response(self, data):
#自定义分页器的返回参数
return CustomResponse(data=data,code=200,msg="OK",status=status.HTTP_200_OK, count=self.page.paginator.count,next=self.get_next_link(),previous=self.get_previous_link(),size=self.page_size,page=self.page.number)
在接口接口视图类获取数据返回时,如果有分页器则使用该分页器自定义的Response返回对象。
class FriendView(viewsets.ModelViewSet):
queryset = Friend.objects.all()
serializer_class = FriendModelSerializer
pagination_class = MyPage
#自定义list方法,自定义Response返回
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
#如果有分页器,则进行分页后返回
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return CustomResponse(data=serializer.data, code=200, msg="OK", status=status.HTTP_200_OK)
接口访问效果如下:
可以看到接口中自定义增加了分页信息。
但是有时候可能希望分页的信息数据要放在data节点里面,这样也是可以做到的。
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from common.customresponse import CustomResponse
class MyPage(PageNumberPagination):
page_size = 8 #每页显示数量
max_page_size = 50 #每页最大显示数量。
page_size_query_param = 'size' #每页数量的参数名称
page_query_param = 'page' #页码的参数名称
#自定义分页器的返回参数
def get_paginated_response(self, data):
ret_data = dict()
ret_data['items'] = data
# 加入自定义分页信息
ret_data['total'] = self.page.paginator.count
ret_data['hasNextPage'] = self.get_next_link()
ret_data['size'] = self.page_size
ret_data['page'] = self.page.number
return CustomResponse(data=ret_data,code=200,msg="OK",status=status.HTTP_200_OK)
接口访问效果如下:
可以看到接口中自定义增加了分页信息,分页的信息数据放在data节点里面了
至此,本文介绍了通过Django的restframework接口框架自定义Response返回对象来自定义返回数据格式。Django的restframework接口框架使用简单方便,拿来即用,能够很大程度上减少代码开发量。
来源:https://blog.csdn.net/fullbug/article/details/125773730
猜你喜欢
- 1 实验环境(1)服务端:本实验基于虚拟机win2008系统的WAMP环境进行,该环境相关配置过程参考文章《【语言环境】WAMP环境部署及优
- 有朋友问,在数据库中如何查询数据所在的行,一般我们建议一个自增字段就可以了.但是有时却会删除数据,那么那个自增字段也不正确了先不管朋友们为什
- AdobeAdobe公司的标识1982年,40多岁的程序员约翰·沃诺克(John Warnock)和查尔斯·杰斯克(Charles Gesc
- 加上设置字符编码的方法:response.setHeader("charset","gb2312")
- 1.ACCESS查询(query_info):select * from info where stu = name1 and age =
- 大多数网站维护都采用“多人协作,共同管理”方式。某个人负责一个(或者多个)栏目,他只能对他负责的栏目进
- 最近Google Code推出了一个面向网站开发者的 * Google DocType。它来自于网站开发者同时又面
- 今天在看框架的时候无意间看到了document.compatMode,经过一番资料查找,终于搞懂了。文档模式在开发中貌似很少用到,最常见的是
- 一、基本思想本文思想是基于用asp和DOM来读取和存储XML数据,并利用XML数据来存储留言信息,达到同用数据库存储数据的功能。二、XML留
- 我们知道,一般的关系数据库(如SQL Server、Oracle、Access等)中的查询操作是支持集合操作的,例如可以用“Update A
- 声明,本文中所称CSS雪碧即为CSS Sprites,这个词组一直没有一个固定或者约定俗成的中文翻译,一些人开始称之为CSS雪碧,我们且当作
- PHP PDO预定义常量以下常量由本扩展模块定义,因此只有在本扩展的模块被编译到PHP中,或者在运行时被动态加载后才有效。注意:PDO使用类
- 用户体验已经是一个老生常谈的话题了。我非常赞同某位达人所说的,用户体验设计应该贯穿于产品从萌芽到出生的整个过程,产品原型、视觉设计、前端开发
- 近来看论坛上经常有人提问关于如何无刷新,自动更新数据.传统上,我们浏览网页,如果加入最新的数据.只能是等我们重新向服务器端请求时才能显示出来
- 昨天在W3C看到,6月10日发布了新的 HTML 5 草案(Working Draft)。粗略的读了一下它提供的 新版本说明文档 ,作了一点
- VBScript似乎已经成为ASP服务器端开发的首先语言,VBScript函数库丰富、而且使用起来也很容易上手,即使平时不太编程的朋友,只要
- Cookie是一种小型文本文件,存储在用户计算机中,用于跟踪用户在互联网上的活动。Cookie通常由网站创建,以便记住用户的偏好和登录状态,
- 平面设计 常用尺寸 三折页广告 标准尺寸: (A4)210mm x 285mm普通宣传册 标准尺寸: (A4)210mm x 285mm文件
- javascript曾一度被认为是玩具型的语言,因为它太容易上手,而且,javascript曾一度担任为web站点“打杂”的职责。直到Aja
- 一.ASP使用SQL查询数据库方法: 方法1 Set&nbs