Django Restframework实现自定义分页

1.自定义分页器

首先继承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,
        })

我们继承这个分页器并重写它,我这里加了响应状态码,可以自己选择性加入要响应的内容。

  • count:表示总记录数
  • next:表示下一页的URL
  • previous:表示上一页的URL
  • results:表示要返回的结果集
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)

 2.视图集

我们通过视图集来对结果进行分页。以下是个示例:

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

Django Restframework实现自定义分页_第1张图片

请求的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的路由列表中

你可能感兴趣的:(Django,django,数据库,python)