REST framework 分页组件

REST framework提供了分页的支持。

我们可以在配置文件settings.py中设置全局的分页方式,如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100  # 每页数目
}


如果在视图内关闭分页功能,只需在视图内设置属性:
pagination_class = None

自定义分页组件:

1.创建pahenations.py文件,在其中自定义分页类(基础分页类/偏移分页类/游标分页类)
2.视图类中配置自定义的分页类: pagination_class = 自定义分页类

基础分页组件

  • pahenations.py
导入PageNumberPagination类
from rest_framework.pagination import PageNumberPagination
​
继承PageNumberPagination类
class MyPageNumberPagination(PageNumberPagination):
    # ?page=页码
    page_query_param = 'page'
    # ?page=页面 下默认一页显示的条数
    page_size = 3
    # ?page=页面&page_size=条数 用户自定义一页显示的条数
    page_size_query_param = 'page_size'
    # 用户自定义一页显示的条数最大限制:数值超过5也只显示5条
    max_page_size = 5

属性:

  • page_size 每页数目
  • page_query_param 前端发送的页数关键字名,默认为"page"
  • page_size_query_param 前端发送的每页数目关键字名,默认为None
  • max_page_size 前端最多能设置的每页数量

使用:

  • views.py
from rest_framework.generics import ListAPIView
​
class CarListAPIView(ListAPIView):
    # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
    pagination_class = pagenations.MyPageNumberPagination

    eg: /cars/?page=2?page_size=10
    每页显示10条,共展示2页

偏移分页组件

  • pahenations.py
导入LimitOffsetPagination类
from rest_framework.pagination import LimitOffsetPagination

继承LimitOffsetPagination类
class MyLimitOffsetPagination(LimitOffsetPagination):
    # ?offset=从头偏移的条数&limit=要显示的条数
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    
    # ?不传offset和limit默认显示前3条,只设置offset就是从偏移位往后再显示3条
    default_limit = 3
    
    # ?limit可以自定义一页显示的最大条数
    max_limit = 5
​
    # 只使用limit结合ordering可以实现排行前几或后几
    # eg: ?ordering=-price&limit=2  => 价格前2

属性:

  • default_limit 默认限制,默认值与PAGE_SIZE设置一直
  • limit_query_param limit参数名,默认'limit'
  • offset_query_param offset参数名,默认'offset'
  • max_limit 最大limit限制,默认None

使用:

  • views.py
from rest_framework.generics import ListAPIView
​
class CarListAPIView(ListAPIView):
    # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
    pagination_class = pagenations.MyLimitOffsetPagination

游标分页组件

  • pahenations.py
注:必须基于排序规则下进行分页
1)如果接口配置了OrderingFilter过滤器,那么url中必须传ordering
2)如果接口没有配置OrderingFilter过滤器,一定要在分页类中声明ordering按某个字段进行默认排序
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 3
    page_size_query_param = 'page_size'
    max_page_size = 5
    ordering = '-pk'

使用:

  • views.py
from rest_framework.generics import ListAPIView
​
class CarListAPIView(ListAPIView):
    # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
    pagination_class = pagenations.MyCursorPagination

野生分页功能

def page_func(request, dirent_list):
    new_dirent_list = sorted(dirent_list, key=lambda x:x.get("time"),reverse=True)

    try:
        current_page = int(request.GET.get('page', '1'))
        per_page = int(request.GET.get('per_page', '10'))
    except ValueError:
        current_page = 1
        per_page = 10

    # 总页数
    page_count = len(new_dirent_list) // per_page  
    if page_count == 0:
        page_count = 1

    start = (current_page - 1) * per_page  # 0
    limit = per_page + start  # 10
    res_list = new_dirent_list[start:limit]
    if len(new_dirent_list[limit:]) >= per_page:
        has_next_page = True
    else:
        res_list = new_dirent_list[start:]
        has_next_page = False
    page_info = {
        'has_next_page': has_next_page,
        'current_page': current_page,
        'page_count': page_count,
    }

    return page_info, res_list

class SearchDirView(APIView):
    authentication_classes = (TokenAuthentication, SessionAuthentication)
    permission_classes = (IsAuthenticated, )
    throttle_classes = (UserRateThrottle, )
    def get(self,request):
        dirent_list = [{}, {}, {},]
        page_info, res_list = page_func(request, dirent_list)
        return Response(
            {
                "has_more": page_info.get("has_next_page"),
                "total": page_info.get("page_count"),
                "current_page": page_info.get("current_page"),
                "results": res_list,
            }
        )

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值