首先继承drf框架的分页器,以下是PageNumberPagination的源码。
def get_paginated_response(self, data):
return Response({
'count': self.page.paginator.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data,
})
我们继承这个分页器并重写它,我这里加了响应状态码,可以自己选择性加入要响应的内容。
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
class CustomPagination(PageNumberPagination):
'''自定义分页器'''
page_size = 1 # 默认每页数量
page_size_query_param = "size" # url参数
max_page_size = 999 # 最大page_size
def get_paginated_response(self, data):
msg_dict = {
'code': 0,
'msg': '成功',
'data': {
'count': self.page.paginator.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data
}
}
if not data:
msg_dict['msg'] = '暂无数据'
msg_dict['data'] = []
return Response(msg_dict)
我们通过视图集来对结果进行分页。以下是个示例:
import json
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from .import CustomPagination # 将自定义的分页器导入
class ResultSerializer(serializers.ModelSerializer):
# 需要序列化(返回给前端)的字段,如果不需要为字段起别名,可以不写以下这三行
name= serializers.CharField(source='f_name')
a= serializers.JSONField(source='f_a')
b= serializers.DateTimeField(source='f_b')
class Meta:
model = TableName # 模型名称
fields = ['name', 'a', 'b'] # 需要序列化的字段 __all__表示全部序列化
# exclude = ['',] # 需要排除序列化的字段
read_only_fields = ['name'] # 只读字段
ordering_fields = ['b'] # 按列表内的字段排序
class ResultViewSet(ModelViewSet):
# 这三个变量名称都是固定的
queryset = TableName.objects.all() # 结果集
serializer_class = ResultSerializer # 序列化器
pagination_class = CustomPagination # 自定义分页器
# 这里是自定义的方法,如果普通的增删改查满足不了需求,可以自定义方法
def history_result(self, request):
body = json.loads(request.body)
name= body.get('name')
a= body.get('a')
id= Table_other.objects.filter(f_name=name, f_a=a).order_by(
'f_b').values('id')
queryset = Table.objects.filter(f_id=id).order_by('f_receive_time')
# 将结果分页
page_queryset = self.paginate_queryset(queryset)
if page_queryset is not None:
# 将结果序列化为json
serializer = ResultSerializer(page_queryset, many=True) # many表示序列化多个对象
return self.get_paginated_response(serializer.data) # 分页返回,这个方法继承自定义分页
serializer = ResultSerializer(queryset, many=True)
return Response(serializer.data)
视图集自带增删改查方法,不清楚的可以去了解一下。 如果自带方法满足不了需求,且还想对结果分页,例如:在示例视图集中,我自定义了一个histotry_result方法(动作),从请求体获得了参数name,a,查询Table_other获得了一个id,再通过这个id查询Table表,获得结果集,后面的代码就是将结果集分页、序列化、以分页的形式返回。
请求的url写法1
不写?... 则默认访问第一页默认size的结果,page=last表示最后一页
http://请求地址/result/all/user?page=1&size=1 请求方式post,调用history_result方法
http://请求地址/result/all?page=1&size=1 请求方式get,返回TableName的结果集
from django.urls import path
from rest_framework.routers import DefaultRouter
from .import ResultViewSet
router = DefaultRouter() # 可以处理视图的路由器
urlpatterns = [
path(r'result/all/user', ResultViewSet.as_view({'post':'history_result'})),
path(r'result/all', ResultViewSet.as_view({'get':'list'})),
]
urlpatterns += router.urls # 将路由器中的所以路由信息追到到django的路由列表中
这种写法不需要在URL末尾添加/,需要在django配置文件中添加以下代码
# 为False表示前端访问URL,结尾可以不用以/结尾
APPEND_SLASH = False
请求的url写法2
不写?... 则默认访问第一页默认size的结果
http://请求地址/result/all/user/?page=1&size=1 请求方式post,调用history_result方法
http://请求地址/result/all/?page=1&size=1 请求方式get,返回TableName的结果集
from django.urls import path
from rest_framework.routers import DefaultRouter
from .import ResultViewSet
router = DefaultRouter() # 可以处理视图的路由器
urlpatterns = [
path(r'result/all/user/', ResultViewSet.as_view({'post':'history_result'})),
path(r'result/all/', ResultViewSet.as_view({'get':'list'})),
]
urlpatterns += router.urls # 将路由器中的所以路由信息追到到django的路由列表中