在DjangoRESTFramework中,分页是处理大量数据返回的核心功能,通过内置的Pagination类可以快速实现数据切片,避免全量数据返回带来的性能问题。DRF的分页逻辑会在视图返回数据前对查询集进行切片处理,只返回当前页的指定数据量,同时可以返回总页数、当前页等辅助信息。

DRF内置分页类介绍
DRF提供了三种常用的内置分页类,分别适用于不同的业务场景,开发者可以直接在视图中配置使用。
1. PageNumberPagination
基于页码的分页方式,用户通过传递页码参数获取对应页的数据,适合大多数常规列表接口场景。
首先需要在配置文件中设置全局分页参数,也可以在视图中单独配置:
# settings.py 全局配置
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10 # 每页默认返回10条数据
}
如果需要在单个视图中自定义分页参数,可以重写分页类的属性:
from rest_framework.pagination import PageNumberPagination
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer
class CustomPageNumberPagination(PageNumberPagination):
page_size = 5 # 每页返回5条数据
page_size_query_param = 'page_size' # 允许前端通过page_size参数自定义每页数量
max_page_size = 20 # 限制前端自定义每页数量的最大值
page_query_param = 'page' # 页码参数名,默认就是page
class BookListView(APIView):
def get(self, request):
queryset = Book.objects.all()
# 创建分页对象
paginator = CustomPageNumberPagination()
# 对查询集进行分页处理
page_data = paginator.paginate_queryset(queryset, request)
# 序列化分页后的数据
serializer = BookSerializer(page_data, many=True)
# 返回分页后的响应,包含分页元数据
return paginator.get_paginated_response(serializer.data)
2. LimitOffsetPagination
基于偏移量的分页方式,用户通过指定起始偏移量和获取数量来切片数据,适合需要精确控制数据范围的场景。
from rest_framework.pagination import LimitOffsetPagination
class CustomLimitOffsetPagination(LimitOffsetPagination):
default_limit = 10 # 默认每页返回10条
limit_query_param = 'limit' # 数量参数名
offset_query_param = 'offset' # 偏移量参数名
max_limit = 50 # 最大限制数量
class BookListView(APIView):
def get(self, request):
queryset = Book.objects.all()
paginator = CustomLimitOffsetPagination()
page_data = paginator.paginate_queryset(queryset, request)
serializer = BookSerializer(page_data, many=True)
return paginator.get_paginated_response(serializer.data)
3. CursorPagination
基于游标的分页方式,通过加密的游标参数获取下一页数据,适合数据实时性高、需要避免页码跳变的场景,性能也优于前两种分页方式。
from rest_framework.pagination import CursorPagination
class CustomCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 游标参数名
page_size = 10 # 每页数量
ordering = '-create_time' # 排序字段,必须指定,用于游标定位
class BookListView(APIView):
def get(self, request):
queryset = Book.objects.all()
paginator = CustomCursorPagination()
page_data = paginator.paginate_queryset(queryset, request)
serializer = BookSerializer(page_data, many=True)
return paginator.get_paginated_response(serializer.data)
自定义分页类实现特殊需求
如果内置分页类无法满足业务需求,比如需要返回额外的统计信息,可以自定义分页类重写相关方法。
例如需要返回当前页数据的同时,返回所有数据的总数:
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
class TotalPageNumberPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 20
def get_paginated_response(self, data):
# 重写响应方法,添加总数据量字段
return Response({
'total_count': self.page.paginator.count,
'total_pages': self.page.paginator.num_pages,
'current_page': self.page.number,
'page_size': self.page_size,
'results': data
})
使用该自定义分页类的视图只需要将分页类替换为TotalPageNumberPagination即可,返回的响应中会包含总数据量、总页数等额外信息。
分页配置注意事项
- 全局配置的分页类会对所有使用DRF分页机制的视图生效,如果某个视图不需要分页,可以在视图中设置
pagination_class = None - 使用
PageNumberPagination时,如果请求的页码超过总页数,会返回空数据列表,不会报错 CursorPagination不支持跳页,只能按顺序获取上一页或下一页数据,适合无限滚动的场景- 分页只对查询集(QuerySet)或列表类型的数据生效,如果是已经处理过的非序列数据,需要先进行转换再分页
通过以上方式,就可以在DjangoRESTFramework中快速实现数据分页功能,根据业务场景选择合适的分页方式,能够有效提升接口的响应速度和用户体验。
DjangoRESTFrameworkPaginationPython数据分页修改时间:2026-07-14 05:18:23