如何在Django REST Framework中实现多种分页方式
实现DRF API多分页方式切换
要让API支持客户端自主选择分页类型,核心是在视图中动态返回对应分页类,具体实现步骤如下:
1. 调整视图代码(views.py)
先导入LimitOffsetPagination,然后重写视图的get_pagination_class方法,根据请求参数判断使用哪种分页逻辑:
from rest_framework import generics from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination from .models import * from .serializers import ProductsSerializer class CustomPageNumberPagination(PageNumberPagination): page_size = 2 # 默认每页数据量 page_size_query_param = 'page_size' # 允许客户端自定义每页数量 max_page_size = 10 # 限制最大每页数据量(建议放宽原代码的2,避免过于严格) class CustomLimitOffsetPagination(LimitOffsetPagination): default_limit = 2 # 默认每页数据量 limit_query_param = 'limit' # 自定义数量的参数名 offset_query_param = 'offset' # 数据偏移量的参数名 max_limit = 10 # 限制单次请求最大数据量 class ProductsAPIList(generics.ListCreateAPIView): queryset = Products.objects.all() serializer_class = ProductsSerializer def get_pagination_class(self): # 根据请求参数pagination_type选择对应分页方式 pagination_type = self.request.query_params.get('pagination_type') if pagination_type == 'page': return CustomPageNumberPagination elif pagination_type == 'limit-offset': return CustomLimitOffsetPagination # 默认使用页码分页 return CustomPageNumberPagination
2. 修正序列化器错误(serializers.py)
原代码中get_photo_url方法引用了不存在的fingerprint字段,需改为模型定义的photo字段:
from rest_framework import serializers from .models import * class ProductsSerializer(serializers.ModelSerializer): class Meta: model = Products fields = "__all__" def get_photo_url(self, obj): request = self.context.get('request') if obj.photo: # 先判断图片是否存在,避免空值报错 photo_url = obj.photo.url return request.build_absolute_uri(photo_url) return None
3. 客户端使用示例
客户端通过指定pagination_type参数即可切换分页方式:
- 页码分页(PageNumber):
GET /api/products/?pagination_type=page&page=1&page_size=3 - 偏移量分页(LimitOffset):
GET /api/products/?pagination_type=limit-offset&limit=3&offset=0 - 不指定
pagination_type时,默认启用页码分页。
关键说明
- 自定义分页类时设置合理的
max_page_size和max_limit,可避免单次请求返回过多数据,保护服务器性能。 - 动态选择分页的逻辑可根据需求调整,比如修改参数名或默认分页方式。
内容的提问来源于stack exchange,提问作者alemax1
相关产品推荐
相关产品推荐

