在前面的DRF系列教程中,我们以博客为例介绍了序列化器, 使用基于类的视图APIView和ModelViewSet开发了针对文章资源进行增删查改的完整API端点,并详细对权限和认证(含jwt认证)进行了总结与演示。在本篇文章中我们将向你演示如何在Django REST Framework中使用分页。
分页
为什么要分页"created"这个字段,否则你要手动指定ordering排序才能进行使用。
使用PageNumberPagination类
DRF中使用默认分页类的最简单方式就是在settings.py中进行全局配置,如下所示:
REST_FRAMEWORK ={ 'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE':2 }
展示效果如下,每页展示两条记录, 不支持用户指定每页展示数据的数量。
但是如果你希望用户按"htmlcode">
from rest_framework.pagination import PageNumberPagination class MyPageNumberPagination(PageNumberPagination): page_size = 2 # default page size page_size_query_param = 'size' # "htmlcode">from rest_framework import viewsets from .pagination import MyPageNumberPagination class ArticleViewSet(viewsets.ModelViewSet): # 用一个视图集替代ArticleList和ArticleDetail两个视图 queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = MyPageNumberPagination # 自行添加,将request.user与author绑定 def perform_create(self, serializer): serializer.save(author=self.request.user) # 自行添加,将request.user与author绑定 def perform_update(self, serializer): serializer.save(author=self.request.user)展示效果如下所示:
当然定制分页类不限于指定page_size和max_page_size这些属性,你还可以改变响应数据的输出格式。比如我们这里希望把next和previous放在一个名为links的key里,我们可以修改MyPageNumberPagination类,重写get_paginated_response方法:
from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response class MyPageNumberPagination(PageNumberPagination): page_size = 2 # default page size page_size_query_param = 'size' # "text-align: center">注意:重写get_paginated_response方法非常有用,你还可以给分页响应数据传递额外的内容,比如code状态码等等。
前面的例子中我们只在单个基于类的视图或视图集中使用到了分页类,你还可以修改settings.py全局使用你自定义的分页类,如下所示。展示效果是一样的,我们就不详细演示了。
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'blog.pagination.MyPageNumberPagination', }使用LimitOffsetPagination类
使用这个分页类最简单的方式就是在settings.py中进行全局配置,如下所示:
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination' }展示效果如下所示,从第6条数据查起,每页展示2条。
你也可以自定义MyLimitOffsetPagination类,在单个视图或视图集中使用,或者全局使用。
from rest_framework.pagination import LimitOffsetPagination class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 5 # default limit per age limit_query_param = 'limit' # default is limit offset_query_param = 'offset' # default param is offset max_limit = 10 # max limit per age使用CursorPagination类
全局使用
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination', 'PAGE_SIZE': 2 }展示效果如下所示:
什么"htmlcode">
from rest_framework.pagination import CursorPagination class MyArticleCursorPagination(CursorPagination): page_size = 3 # Default number of records per age page_size_query_param = 'page_size' cursor_query_param = 'cursor' # Default is cursor ordering = '-create_date'修改settings.py, 使用自己定义的分页类。
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'blog.pagination.MyArticleCursorPagination', }响应效果如下所示,你将得到previous和next分页链接。页码都加密了, 链接里不再显示页码号码。默认每页展示3条记录, 如果使用"text-align: center">
当然由于这个ordering字段与模型相关,我们并不推荐全局使用自定义的CursorPagination类,更好的方式是在GenericsAPIView或视图集viewsets中通过pagination_class属性指定,如下所示:
from rest_framework import viewsets from .pagination import MyArticleCursorPagination class ArticleViewSet(viewsets.ModelViewSet): # 用一个视图集替代ArticleList和ArticleDetail两个视图 queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = MyArticleCursorPagination # 自行添加,将request.user与author绑定 def perform_create(self, serializer): serializer.save(author=self.request.user) # 自行添加,将request.user与author绑定 def perform_update(self, serializer): serializer.save(author=self.request.user)函数类视图中使用分页类
注意pagination_class属性仅支持在genericsAPIView和视图集viewset中配置使用。如果你使用函数或简单的APIView开发API视图,那么你需要对你的数据进行手动分页,一个具体使用例子如下所示:
from rest_framework.pagination import PageNumberPagination class ArticleList0(APIView): """ List all articles, or create a new article. """ def get(self, request, format=None): articles = Article.objects.all() page = PageNumberPagination() # 产生一个分页器对象 page.page_size = 3 # 默认每页显示的多少条记录 page.page_query_param = 'page' # 默认查询参数名为 page page.page_size_query_param = 'size' # 前台控制每页显示的最大条数 page.max_page_size = 10 # 后台控制显示的最大记录条数,防止用户输入的查询条数过大 ret = page.paginate_queryset(articles, request) serializer = ArticleSerializer(ret, many=True) return Response(serializer.data)小结
本文总结了DRF提供的3种分页类并详细演示了如何使用它们,你学会了吗?
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]