python测试开发django-rest-framework-87.分页查询之偏移分页(LimitOffsetPagination)和游标分页(CursorPagination)
前言
django-rest-framework 分页器提供了3中分页方式,前面一篇介绍了简单分页 (PageNumberPagination),
本篇继续介绍另外2个分页偏移分页 (LimitOffsetPagination) 和游标分页 (CursorPagination)
偏移分页 (LimitOffsetPagination)
LimitOffsetPagination 是偏移分页,查询的时候url地址带上 limit 和 offset 2个参数,如下格式
可以重写 LimitOffsetPagination 类,定义查询的一些参数配置
- default_limit = api_settings.PAGE_SIZE # 默认条数
- limit_query_param = 'limit' # 查询时,查询参数及指定查询多少条
- offset_query_param = 'offset' # 查询时,指定的起始位置是哪
- max_limit = None # 查询时,最多返回多少条
先导入LimitOffsetPagination
# 分页器 -- 偏移分页
from rest_framework.pagination import LimitOffsetPagination
class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = 5 # 设置每页显示的数量为5,那么查询结果默认返回5条
limit_query_param = 'limit' # 优先使用limit_query_param来设置显示条数
offset_query_param = 'offset' # 偏移数,查询时,指定的起始位置是哪
max_limit = 20 # 查询时,最多返回多少条
APIView使用分页查询
写查询视图的时候,先序列化,再定义分页器,查询的时候可以带上参数/api/v1/goods?limit=100&offset=10
from rest_framework import serializers
from .models import Goods
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated, AllowAny
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
# 序列化 Goods 模型
class GoodsAPISerializer(serializers.ModelSerializer):
class Meta:
model = Goods
fields = '__all__' # 返回全部的字段
# 分页器 -- 偏移分页
class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = 5 # 设置每页显示的数量为5,那么查询结果默认返回5条
limit_query_param = 'limit' # 优先使用limit_query_param来设置显示条数
offset_query_param = 'offset' # 偏移数,查询时,指定的起始位置是哪
max_limit = 20 # 查询时,最多返回多少条
# 查询视图
class GoodsAPISView(APIView):
permission_classes = (AllowAny,) # AllowAny 允许所有用户
def get(self, request, *args, **kwargs):
'''返回所有的'''
page = MyLimitOffsetPagination()
goods = Goods.objects.all() # 查询全部
ret = page.paginate_queryset(goods, request)
serializer = GoodsAPISerializer2(ret, many=True)
return Response({
"code": 0,
"msg": "success!",
"data": serializer.data
})
如果我们访问http://localhost:8000/api/v1/goods?offset=10&limit=3
那么就是从查询的结果里面第10条数据往后面取3条数据
{
"code": 0,
"msg": "success!",
"data": [{
"id": 109,
"create_time": "2021-01-17 10:14:41",
"update_time": "2021-01-17 10:14:41",
"goodsname": "pytest入门到精",
"goodscode": "sp_100010",
"merchantid": "10001",
"merchantname": "悠悠学堂",
"goodsprice": 68.8,
"stock": 10000,
"goodsgroupid": 0,
"goodsstatus": 1
}, {
"id": 110,
"create_time": "2021-01-17 10:15:44",
"update_time": "2021-01-17 10:15:44",
"goodsname": "pytest入门到精",
"goodscode": "sp_100011",
"merchantid": "10001",
"merchantname": "悠悠学堂",
"goodsprice": 68.8,
"stock": 10000,
"goodsgroupid": 0,
"goodsstatus": 1
}, {
"id": 111,
"create_time": "2021-01-17 10:24:13",
"update_time": "2021-01-17 10:24:13",
"goodsname": "pytest入门到精",
"goodscode": "sp_100012",
"merchantid": "10001",
"merchantname": "悠悠学堂",
"goodsprice": 68.8,
"stock": 10000,
"goodsgroupid": 0,
"goodsstatus": 1
}]
}
加密游标分页(CursorPagination)
游标分页(CursorPagination)的特点是速度快,但不能指定指定查询
定义CursorPagination查询的一些参数配置
- cursor_query_param = 'cursor' # 查询的时候,指定的查询方式,默认'cursor'
- page_size = 3 # 每页显示的条数
- page_size_query_param = 'size' # 设置size查询参数,默认None
- max_page_size = 20 # 最多显示条数
- ordering = 'pk' # 默认排序规则:按pk从小到大排序,-pk表示从大到小排序
先导入CursorPagination
# 分页器 -- 加密游标分页
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
page_size = 5 # 默认每页的条数
page_size_query_param = 'size' # 查询参数size
max_page_size = 20 # 最大每页的条数
ordering = 'pk' # 默认排序规则:按pk从小到大排序,-pk表示从大到小排序
APIView使用加密游标分页
只能从第一页开始查询,查询的时候结果里面返回了下一页的游标值:cursor=加密串
from rest_framework import serializers
from .models import Goods
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated, AllowAny
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
# 序列化 Goods 模型
class GoodsAPISerializer(serializers.ModelSerializer):
class Meta:
model = Goods
fields = '__all__' # 返回全部的字段
# 分页器 -- 加密游标分页
class MyCursorPagination(CursorPagination):
page_size = 5 # 默认每页的条数
page_size_query_param = 'size' # 查询参数size
max_page_size = 20 # 最大每页的条数
ordering = 'pk' # 默认排序规则:按pk从小到大排序,-pk表示从大到小排序
# 查询视图
class GoodsAPISView(APIView):
permission_classes = (AllowAny,) # AllowAny 允许所有用户
def get(self, request, *args, **kwargs):
'''返回所有的'''
page = MyCursorPagination()
goods = Goods.objects.all() # 查询全部
ret = page.paginate_queryset(goods, request)
serializer = GoodsAPISerializer2(ret, many=True)
return Response({
"code": 0,
"msg": "success!",
"next": page.get_next_link(),
"data": serializer.data
})
)
查询的时候时候先访问首页http://localhost:8000/api/v1/goods?size=3
{
"code": 0,
"msg": "success!",
"next": "http://localhost:8000/api/v1/goods?cursor=cD0xNA%3D%3D&size=3",
"data": [{
"id": 1,
"create_time": "2021-01-17 15:14:25",
"update_time": "2021-01-19 15:55:17",
"goodsname": "《selenium 入门到精通》--修改课程名称",
"goodscode": "sp_100049",
"merchantid": "10001",
"merchantname": "悠悠学堂",
"goodsprice": 49.0,
"stock": -444,
"goodsgroupid": 0,
"goodsstatus": 1
}, {
"id": 13,
"create_time": "2021-01-16 20:12:36",
"update_time": "2021-01-17 09:41:05",
"goodsname": "《selenium入门到精通》",
"goodscode": "sp_100008",
"merchantid": "10001",
"merchantname": "悠悠学堂",
"goodsprice": 49.9,
"stock": 100,
"goodsgroupid": 0,
"goodsstatus": 1
}, {
"id": 14,
"create_time": "2021-01-16 20:12:42",
"update_time": "2021-01-17 09:41:05",
"goodsname": "《selenium入门到精通》",
"goodscode": "sp_100009",
"merchantid": "10001",
"merchantname": "悠悠学堂",
"goodsprice": 49.9,
"stock": 100,
"goodsgroupid": 0,
"goodsstatus": 1
}]
}
从返回的结果里面自动生成下一页的 cursor 游标值(加密串,自动生成的),于是就可以根据next的访问下一页数据
http://localhost:8000/api/v1/goods?cursor=cD0xNA%3D%3D&size=3
加密游标分页的优点是安全性高,每次必须拿到cursor=加密串才能访问下一页的数据
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2018-01-19 selenium+python自动化89-用例不通过的时候发送邮件