12 排序与分页
有时,客户端希望 RESTful Web API 提供经过排序后的字段,比如,按照年龄从大到小排列学生;有时,根据客户端条件,需要返回给前端的数据过多,如果一次提供,会大大降低响应速度。此时,可将数据做分割,分成不同的小份,发送给客户端。这一节,我们为大家介绍 RESTful Web API 如何实现数据的排序与分页。
1.排序的使用
在类视图中设置 filter_backends,使用rest_framework.filters.OrderingFilter
过滤器,REST framework 会在请求的查询字符串参数中检查是否包含了 ordering 参数,如果包含了 ordering 参数,则按照 ordering 参数指明的排序字段对数据集进行排序。
前端可以传递的 ordering 参数的可选字段值需要在 ordering_fields 中指明。
示例:
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
filter_backends = [OrderingFilter]
ordering_fields = ('id', 's_age', 's_number')
此时,访问 http://127.0.0.1:8000/api/students/?ordering=-s_age ,服务器返回按年龄逆序排序后的学生信息。
2.分页的使用
REST framework 提供了分页的支持。
有时,前端根据一定的条件查询的数据量是惊人的,如果按照查询条件,一次性返回所有数据,往往会使服务器承受巨大的压力,此时我们可以以分页的方式提供数据,相当于将庞大的数据打散,每次只按要求返回一定数量的数据,就可以减轻服务器压力。在 Django Rest framework 中,可以在配置文件中设置全局的分页方式,如:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100 # 每页返回的数据条数
}
也可通过自定义 Pagination 类,来为视图添加不同分页行为。在视图中通过pagination_clas 属性来指明。
class LargeResultsSetPagination(PageNumberPagination):
page_size = 1000
page_size_query_param = 'page_size'
max_page_size = 10000
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
pagination_class = LargeResultsSetPagination
注意:如果需要关闭分页功能,只需在视图内设置
pagination_class = None
3.自定义分页器
如果默认的分页功能无法满足要求,可以自行定义分页器。
3.1 PageNumberPagination
前端访问网址形式:
GET http://127.0.0.1/api/students/?page=4
可以在子类中定义的属性:
- page_size :每页数目;
- page_query_param :前端发送的页数关键字名,默认为"page";
- page_size_query_param :前端发送的每页数目关键字名,默认为None;
- max_page_size :前端最多能设置的每页数量。
from rest_framework.pagination import PageNumberPagination
class StandardPageNumberPagination(PageNumberPagination):
page_size_query_param = 'page_size' # 每页数据条数
max_page_size = 10
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
pagination_class = StandardPageNumberPagination
3.2 LimitOffsetPagination
前端访问网址形式:
GET http://127.0.0.1/api/students/?limit=100&offset=400
可以在子类中定义的属性:
- default_limit: 默认限制,默认值与
PAGE_SIZE
设置为一致; - limit_query_param limit:参数名,默认 'limit;
- offset_query_param: offset 参数名,默认 ‘offset’;
- max_limit :最大 limit 限制,默认 None。
from rest_framework.pagination import LimitOffsetPagination
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
pagination_class = LimitOffsetPagination
4.小结
本小节介绍了排序和分页功能,这两个功能也是开发中使用频率较高的功能,排序功能可以按一定顺序返回数据,而分页功能可以减轻服务器压力,节省客户端得到响应的时间。在使用分页时,要注意 offset(偏移量)参数,很多返回的数据与理想数据不一致,通常都是该参数出现了问题。大家要理解核心原理,这样才能在使用时得心应手。