DRF 返回数据的封装,和分页
DRF 返回数据的封装,和分页
1 返回值的 封装
自定义一个类,初始化基本的返回数据信息
class BaseResponse(object):
"""
初始化基本的返回数据信息
"""
def __init__(self,status=True,data=None,error=None):
self.status = status
self.data = data
self.error = error
@property
def get_data(self):
return self.__dict__
视图
class IndexView(APIView):
def get(self,request,version):
ret = BaseResponse() # 获取初始的数据信息
try:
user_list = UserInfo.objects.all()
ser = IndexSerializer(user_list,many=True)
ret.data=ser.data
except Exception as e:
ret.status = False
ret.error = '错误'
return Response(ret.get_data)
2 分页的实现
数据量大的时候,如何实现分页
a. 记录 当前访问页面的数据id --- 数据id
b. 不显示全部页面 只显示一部分页面
c. 只显示上一页 下一页 (url 中的页码进行加密)
mysql 解决分页查询的优化方法
分页是 limit + offset 实现
offset定位,limit取数据,会扫描之前所有的数据,这样越往后,数据量就会越大,查询的速度也会越来越慢
解决方法 -- 利用id索引覆盖
id字段是主键,自然包含默认的主键索引。
利用覆盖索引,只包含id列:
select id from product limit 866613, 20 0.2秒
select * from product limit 866613, 20 37.44秒
这样提升了大概100多倍的速度
使用:
记录起始 id,查询条件ID >
SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20
(1) 基于 limit 和 offset 实现
/api/v2/index/?limit=1&offset=2
LimitOffsetPagination:
class MyPagination(LimitOffsetPagination):
max_limit = 1
default_limit = 2
limit_query_param = 'limit'
offset_query_param = 'offset'
class IndexView(APIView):
def get(self,request,version):
ret = BaseResponse() # 获取初始的数据信息
p = MyPagination()
try:
user_list = UserInfo.objects.all()
page_user_list = p.paginate_queryset(queryset=user_list,request=request,view=self)
ser = IndexSerializer(instance=page_user_list,many=True)
ret.data = ser.data
ret.next = p.get_next_link() # 添加 下一页的url
ret.prev = p.get_previous_link() # 添加 上一页的url
except Exception as e:
ret.status = False
ret.error = '错误'
return Response(ret.get_data)
Response,get _ paginated _ response两种返回值的区别
return p.get_paginated_response(ser.data) -- 带有上一页和下一页 的返回值
(2) 基于 pageNum 实现 分页
/api/v2/index/?page=1&size=3
PageNumberPagination
class MyPagination2(PageNumberPagination):
page_size = 2
page_query_param = 'page'
page_size_query_param = 'size'
max_page_size = 2
(3) 基于 cursor 页码加密 实现
http://127.0.0.1:8000/api/v2/index/?cursor=cD0y&size=2
CursorPagination
class MyPagination3(CursorPagination):
cursor_query_param = 'cursor'
ordering = 'id'
page_size = 2
max_page_size = 2
page_size_query_param = 'size'
读书使人心眼明亮