Fork me on GitHub

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'
posted @ 2018-03-03 15:20  派对动物  阅读(1011)  评论(0编辑  收藏  举报
Top