本文来源于微信公众号:Python野路子
当要查询的数据列表视图会返回很多实例,如果一次将这些数据查询出来,会加大了服务器内存的负载,降低系统的运行速度,所以我们想要给这些结果分页,分页后允许API客户端访问每个单页。
DRF提供了几种分页类:
- PageNumberPagination:普通分页器。按?page=3&page_size=10这种更灵活的方式进行查询,这样用户不仅可以选择页码,还可以选择每页展示数据的数量。还需要设置max_page_size这个参数限制每一页展示数据的最大数量,以防止用户恶意查询(例如,size=100000)。
- LimitOffsetPagination:偏移分页器。按?limit=20&offset=100这种方式进行查询。offset是查询数据的起始点,limit是每页展示数据的最大条数,类似于page_size。当你使用这个类时,你通常还需要设置max_limit这个参数来限制展示给用户数据的最大数量。
**注意:**只有GenericAPIView及其子类(二级视图,三级视图,视图集中的GenericViewSet及其子类)才能使用分页类,APIView,ViewSet不能使用系统的分页。
PageNumberPagination
使用方法
设置可以用分页改变默认的列表风格,我们只要在配置文件种设置全局的分页方式:
REST_FRAMEWORK = {
# 分页
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 3, # 每页多少条记录
}
# views.py
class UserView(ListCreateAPIView):
'''用户注册'''
# 查询结果集
queryset = User.objects.all()
# 序列化器
serializer_class = UserSerializer
这样我们就设置了数据,但是这种全局设置,对于所有继承了DRF视图类的都有效果。
我们也可以单独在 GenericAPIView 子类中,您还可以设置 pagination_class 属性,以便在每个视图的基础上选择 PageNumberPagination。
pagination_class = PageNumberPagination
实际上,往往我们需要自定义分页器。
自定义分页器
我们自定义一个UserNumberPagination类,该类继承了PageNumberPagination类。
from rest_framework.pagination import PageNumberPagination
class UserNumberPagination(PageNumberPagination):
'''自定义普通分页器'''
# 表示每页的默认显示数量
page_size = 5
# 客户端控制每页显示条数的参数名(?size=10)
page_size_query_param = 'size' # 表示url中每页数量参数
page_query_param = 'p' # 表示url中的页码参数
max_page_size = 7 # 表示每页最大显示数量,做限制使用,避免突然大量的查询数据,数据库崩溃
class UserView(ListCreateAPIView):
'''用户注册'''
# 查询结果集
queryset = User.objects.all()
# 序列化器
serializer_class = UserSerializer
# 使用自定义分页器
pagination_class = UserNumberPagination
这样,我们可以使用
这样每页记录数,就是按照自定义类中page_size设置的数值显示每页记录数。
我们也可以按照page_size_query_param值动态传每页记录数。
这样动态改变了每页记录数,为了防止客户恶意查询,比如每页显示10000条数据,所以还需要通过max_page_size进行限制。
这样当我们size=8时,因为设置了max_page_size=7,所以每页显示记录数还是7条记录。
LimitOffsetPagination
这种分页样式反映了查找多个数据库记录时使用的语法。包括limit和offset查询参数。limit指示要返回的项目的最大数目,这相当于其他样式中的 page_size。offset指示查询相对于完整的未分页项的起始位置。
使用方法
全局配置:
REST_FRAMEWORK = {
# 分页
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 3, # 每页多少条记录
}
# views.py
class UserView(ListCreateAPIView):
'''用户注册'''
# 查询结果集
queryset = User.objects.all()
# 序列化器
serializer_class = UserSerializer
这样我们就设置了数据,但是这种全局设置,对于所有继承了DRF视图类的都有效果。
我们也可以单独在 GenericAPIView 子类中,您还可以设置 pagination_class 属性,以便在每个视图的基础上选择 LimitOffsetPagination。
自定义偏移分页器
同样,我们可以自定义重写“LimitOffsetPagination` 类以修改分页样式的属性。
class UserOffsetPagination(LimitOffsetPagination):
'''自定义位移分页器'''
# 表示每页的默认显示数量
default_limit = 5
limit_query_param = 'limit' # 指示“limit”查询参数的名称。默认为 'limit'。
offset_query_param = 'offset' # 指示“offset”查询参数的名称。默认为 'offset'。
max_limit = 7 # 表示每页最大显示数量,做限制使用,避免突然大量的查询数据,数据库崩溃
class UserView(ListCreateAPIView):
'''用户注册'''
# 查询结果集
queryset = User.objects.all()
# 序列化器
serializer_class = UserSerializer
# 使用自定义分页器
pagination_class = UserOffsetPagination
普通视图分页
pagination_class属性仅支持在genericsAPIView和其子类以及视图集ViewSet中配置使用。如果使用函数或简单的APIView,那么需要对数据进行手动分页。
复制网上个参考例子:
from rest_framework.pagination import PageNumberPagination
class UserView(APIView):
"""
显示所有文章
"""
def get(self, request, format=None):
users = User.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(users, request)
serializer = UserSerializer(ret, many=True)
return Response(serializer.data)
今天的文章「DRF系列」-分页分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/8027.html