django---rest-framework下的分页

      • 初始化工作
      • LimitOffsetPagination
      • PageNumberPagination
      • CursorPagination
      • ModelViewSet
      • 版本控制

这篇笔记主要是学习使用rest-framework分页的示例,后续在将其框架的分页源码分析下

初始化工作

models数据

from django.db import models

class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish")
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title

class Publish(models.Model):
    name=models.CharField(max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    def __str__(self):
        return self.name

url路由配置

 url("paginator_apiview1/$", views.Paginator_apiview1.as_view()),
    url("paginator_apiview2/$", views.Paginator_apiview2.as_view()),
    url("paginator_apiview3/$", views.Paginator_apiview3.as_view()),
    url("paginator_apiview4/$", views.Paginator_apiview4.as_view()),

ModelSerializer


class BookSerializers(serializers.ModelSerializer):

    class Meta:
        model=Book
        fields="__all__"

    # publish=serializers.HyperlinkedIdentityField(
    #     view_name="publish_detail",
    #     lookup_field="publish_id",
    #     lookup_url_kwarg="pk"
    #     # publishes/(?P\d+)/$
    # )

    authors = serializers.SerializerMethodField()
    def get_authors(self,obj):
        temp=[]
        for author in obj.authors.all():
            temp.append({"pk":author.pk,"name":author.name})
        return temp

LimitOffsetPagination

from rest_framework.views import  APIView,Response
from rest_framework.pagination import LimitOffsetPagination

class P1(LimitOffsetPagination):
     max_limit = 3  # 最大限制默认是None
     default_limit =2  # 设置每一页显示多少条
     limit_query_param = 'limit'  # 往后取几条
     offset_query_param = 'offset'  # 当前所在的位置


class Paginator_apiview1(APIView):
    def get(self,request,*args,**kwargs):
        user_list = Book.objects.all()
        p1 = P1()  # 注册分页
        page_user_list = p1.paginate_queryset(queryset=user_list, request=request, view=self)
        print('打印的是分页的数据', page_user_list)
        ser = BookSerializers(instance=page_user_list, many=True)  # 可允许多个
        # return Response(ser.data) #不含上一页下一页
        return p1.get_paginated_response(ser.data)

http://127.0.0.1:8000/paginator_apiview1/?limit=2&offset=2

{
  "count": 8,
  "next": "http://127.0.0.1:8000/paginator_apiview1/?limit=2&offset=4",
  "previous": "http://127.0.0.1:8000/paginator_apiview1/?limit=2",
  "results": [
    {
      "id": 9,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "oracle",
      "price": 3,
      "pub_date": "2018-04-11",
      "publish": 2
    },
    {
      "id": 10,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "java",
      "price": 32,
      "pub_date": "2018-04-11",
      "publish": 1
    }
  ]
}

或者如下:

from rest_framework import views
class BaseResponse(object):
    def __init__(self,code=1000,data=None,error=None):
        self.code = code
        self.data = data
        self.error = error
class Paginator_apiview2(views.APIView):
    '''第二种类表示的方式'''
    def get(self,request,*args,**kwargs):
        ret = BaseResponse()
        try:
            user_list = Book.objects.all()
            p1 = P1()
            page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self)
            ser = BookSerializers(instance=page_user_list,many=True)
            ret.data = ser.data
            ret.next = p1.get_next_link()
        except Exception as e:
            ret.code= 1001
            ret.error = 'xxxx错误'
        return Response(ret.__dict__)

http://127.0.0.1:8000/paginator_apiview2/?limit=2&offset=2

{
  "code": 1000,
  "data": [
    {
      "id": 9,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "oracle",
      "price": 3,
      "pub_date": "2018-04-11",
      "publish": 2
    },
    {
      "id": 10,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "java",
      "price": 32,
      "pub_date": "2018-04-11",
      "publish": 1
    }
  ],
  "error": null,
  "next": "http://127.0.0.1:8000/paginator_apiview2/?limit=2&offset=4"
}

PageNumberPagination

from rest_framework.pagination import PageNumberPagination,CursorPagination
class P2(PageNumberPagination):
    #默认每页显示的数据条数
    page_size = 2
    #获取url参数中设置的每页显示数据条数
    page_size_query_param = 'size'
    #获取url中传入的页码key
    page_query_param = 'page'
    #最大支持的每页显示的数据条数
    max_page_size = 5

class Paginator_apiview3(APIView):
    #使用http://127.0.0.1:8080/app01/v1/index3/?page=1&page_size=1可进行判断
    def get(self,request,*args,**kwargs):
        user_list = Book.objects.all()
        #实例化分页对象,获取数据库中的分页数据
        p2 = P2()
        page_user_list = p2.paginate_queryset(queryset=user_list,request=request,view=self)
        print('打印的是分页的数据',page_user_list)

        #序列化对象
        ser = BookSerializers(instance=page_user_list,many=True)  #可允许多个

        #生成分页和数据
        # return Response(ser.data) #不含上一页下一页
        return p2.get_paginated_response(ser.data)

http://127.0.0.1:8000/paginator_apiview3/?page=2

{
  "count": 8,
  "next": "http://127.0.0.1:8000/paginator_apiview3/?page=3",
  "previous": "http://127.0.0.1:8000/paginator_apiview3/",
  "results": [
    {
      "id": 9,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "oracle",
      "price": 3,
      "pub_date": "2018-04-11",
      "publish": 2
    },
    {
      "id": 10,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "java",
      "price": 32,
      "pub_date": "2018-04-11",
      "publish": 1
    }
  ]
}

CursorPagination

class P3(CursorPagination):
    # URL传入的游标参数
    cursor_query_param = 'cursor'
    # 默认每页显示的数据条数
    page_size = 2
    # URL传入的每页显示条数的参数
    page_size_query_param = 'size'
    # 每页显示数据最大条数
    max_page_size = 3

    # 根据ID从大到小排列
    ordering = "id"


class Paginator_apiview4(APIView):
    def get(self, request, *args, **kwargs):
        user_list = Book.objects.all().order_by('-id')
        p3 = P3()  # 注册分页
        page_user_list = p3.paginate_queryset(queryset=user_list, request=request, view=self)
        print('打印的是分页的数据', page_user_list)
        ser = BookSerializers(instance=page_user_list, many=True)  # 可允许多个
        # return Response(ser.data) #不含上一页下一页
        return p3.get_paginated_response(ser.data)

http://127.0.0.1:8000/paginator_apiview4/?cursor=cD04

{
  "next": "http://127.0.0.1:8000/paginator_apiview4/?cursor=cD0xMA%3D%3D",
  "previous": "http://127.0.0.1:8000/paginator_apiview4/?cursor=cj0xJnA9OQ%3D%3D",
  "results": [
    {
      "id": 9,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "oracle",
      "price": 3,
      "pub_date": "2018-04-11",
      "publish": 2
    },
    {
      "id": 10,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "java",
      "price": 32,
      "pub_date": "2018-04-11",
      "publish": 1
    }
  ]
}

ModelViewSet

from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination

class MyPageNumberPagination(PageNumberPagination):
    page_size=2
    page_query_param="page_num"
    page_size_query_param="size"
    max_page_size=5


from app01.service.auth import *

from rest_framework.viewsets import  ModelViewSet
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializers
    pagination_class = MyPageNumberPagination

http://127.0.0.1:8000/books/?page_num=2

{
  "count": 8,
  "next": "http://127.0.0.1:8000/books/?page_num=3",
  "previous": "http://127.0.0.1:8000/books/",
  "results": [
    {
      "id": 9,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "oracle",
      "price": 3,
      "pub_date": "2018-04-11",
      "publish": 2
    },
    {
      "id": 10,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "java",
      "price": 32,
      "pub_date": "2018-04-11",
      "publish": 1
    }
  ]
}

或者如下:

class MyPageNumberPagination(CursorPagination):
    cursor_query_param="page"
    page_size=2
    ordering="id"


from app01.service.auth import *

from rest_framework.viewsets import  ModelViewSet
class BookViewSet(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializers
    pagination_class = MyPageNumberPagination

http://127.0.0.1:8000/books/?page=cD04

{
  "next": "http://127.0.0.1:8000/books/?page=cD0xMA%3D%3D",
  "previous": "http://127.0.0.1:8000/books/?page=cj0xJnA9OQ%3D%3D",
  "results": [
    {
      "id": 9,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "oracle",
      "price": 3,
      "pub_date": "2018-04-11",
      "publish": 2
    },
    {
      "id": 10,
      "authors": [
        {
          "pk": 1,
          "name": "safly"
        }
      ],
      "title": "java",
      "price": 32,
      "pub_date": "2018-04-11",
      "publish": 1
    }
  ]
}

版本控制

 url(r'^api/(?Pv1)/$', views.UserView1.as_view()),
REST_FRAMEWORK={
  'VERSION_PARAM':'version',
                'DEFAULT_VERSION':'v1',
                'ALLOWED_VERSIONS':['v1','v2'],
}
class UserView1(APIView):
    versioning_class = URLPathVersioning
    def get(self,request,*args,**kwargs):
        print(request.version,args,kwargs)
        print(request.versioning_scheme)
        if request.version=='v2':
            return Response('我是版本二')
        elif request.version=='v1':
            return Response('我是版本一')
        else:
            return Response('其他')

你可能感兴趣的:(PythonWeb框架)