Django rest framework(7)----分页

第一种分页  PageNumberPagination

基本使用

(1)urls.py

urlpatterns = [
    re_path('(?P<version>[v1|v2]+)/page1/', Pager1View.as_view(),)    #分页1
]

(2)api/utils/serializers/pager.py

# api/utils/serializsers/pager.py

from rest_framework import serializers
from api import models


class PagerSerialiser(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = "__all__"

(3)views.py

from api.utils.serializsers.pager import PagerSerialiser
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination


class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        #获取所有数据
        roles = models.Role.objects.all()
        #创建分页对象
        pg = PageNumberPagination()
        #获取分页的数据
        page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #对数据进行序列化
        ser = PagerSerialiser(instance=page_roles,many=True)
        return Response(ser.data)

(4)settings配置

REST_FRAMEWORK = {
    #分页
    "PAGE_SIZE":2   #每页显示多少个
}

自定义分页类

#自定义分页类
class MyPageNumberPagination(PageNumberPagination):
    #每页显示多少个
    page_size = 3
    #默认每页显示3个,可以通过传入pager1/?page=2&size=4,改变默认每页显示的个数
    page_size_query_param = "size"
    #最大页数不超过10
    max_page_size = 10
    #获取页码数的
    page_query_param = "page"


class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        #获取所有数据
        roles = models.Role.objects.all()
        #创建分页对象,这里是自定义的MyPageNumberPagination
        pg = MyPageNumberPagination()
        #获取分页的数据
        page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #对数据进行序列化
        ser = PagerSerialiser(instance=page_roles,many=True)
        return Response(ser.data)

第二种分页   LimitOffsetPagination

 自定义

#自定义分页类2
class MyLimitOffsetPagination(LimitOffsetPagination):
    #默认显示的个数
    default_limit = 2
    #当前的位置
    offset_query_param = "offset"
    #通过limit改变默认显示的个数
    limit_query_param = "limit"
    #一页最多显示的个数
    max_limit = 10


class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        #获取所有数据
        roles = models.Role.objects.all()
        #创建分页对象
        pg = MyLimitOffsetPagination()
        #获取分页的数据
        page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #对数据进行序列化
        ser = PagerSerialiser(instance=page_roles,many=True)
        return Response(ser.data)

 返回的时候可以用get_paginated_response方法

自带上一页下一页

第三种分页 CursorPagination

 加密分页方式,只能通过点“上一页”和下一页访问数据

#自定义分页类3 (加密分页)
class MyCursorPagination(CursorPagination):
    cursor_query_param = "cursor"
    page_size = 2     #每页显示2个数据
    ordering = 'id'   #排序
    page_size_query_param = None
    max_page_size = None

class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        #获取所有数据
        roles = models.Role.objects.all()
        #创建分页对象
        pg = MyCursorPagination()
        #获取分页的数据
        page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #对数据进行序列化
        ser = PagerSerialiser(instance=page_roles,many=True)
        # return Response(ser.data)
        return pg.get_paginated_response(ser.data)

代码

版本、解析器、序列化和分页

# MyProject2/urls.py

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    #path('admin/', admin.site.urls),
    path('api/',include('api.urls') ),
]
# api/urls.py

from django.urls import path,re_path
from .views import UserView,PaserView,RolesView,UserInfoView,GroupView,UserGroupView
from .views import Pager1View

urlpatterns = [
    re_path('(?P<version>[v1|v2]+)/users/', UserView.as_view(),name = 'api_user'),  #版本
    path('paser/', PaserView.as_view(),),   #解析
    re_path('(?P<version>[v1|v2]+)/roles/', RolesView.as_view()),     #序列化
    re_path('(?P<version>[v1|v2]+)/info/', UserInfoView.as_view()),   #序列化
    re_path('(?P<version>[v1|v2]+)/group/(?P<pk>\d+)/', GroupView.as_view(),name = 'gp'),    #序列化生成url
    re_path('(?P<version>[v1|v2]+)/usergroup/', UserGroupView.as_view(),),    #序列化做验证
    re_path('(?P<version>[v1|v2]+)/pager1/', Pager1View.as_view(),)    #分页1
]
# api/models.py

from django.db import models

class UserInfo(models.Model):
    USER_TYPE = (
        (1,'普通用户'),
        (2,'VIP'),
        (3,'SVIP')
    )

    user_type = models.IntegerField(choices=USER_TYPE)
    username = models.CharField(max_length=32,unique=True)
    password = models.CharField(max_length=64)
    group = models.ForeignKey('UserGroup',on_delete=models.CASCADE)
    roles = models.ManyToManyField('Role')


class UserToken(models.Model):
    user = models.OneToOneField('UserInfo',on_delete=models.CASCADE)
    token = models.CharField(max_length=64)


class UserGroup(models.Model):
    title = models.CharField(max_length=32)


class Role(models.Model):
    title = models.CharField(max_length=32)
# api/views.py
import json

from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.versioning import URLPathVersioning
from . import models

##########################################版本和解析器#####################################################

class UserView(APIView):

    def get(self,request,*args,**kwargs):
        #获取版本
        print(request.version)
        #获取处理版本的对象
        print(request.versioning_scheme)
        #获取浏览器访问的url,reverse反向解析
        #需要两个参数:viewname就是url中的别名,request=request是url中要传入的参数
        #(?P<version>[v1|v2]+)/users/,这里本来需要传version的参数,但是version包含在request里面,所有只需要request=request就可以
        url_path = request.versioning_scheme.reverse(viewname='api_user',request=request)
        print(url_path)
        self.dispatch
        return HttpResponse('用户列表')

# from rest_framework.parsers import JSONParser,FormParser

class PaserView(APIView):
    '''解析'''
    # parser_classes = [JSONParser,FormParser,]
    #JSONParser:表示只能解析content-type:application/json的头
    #FormParser:表示只能解析content-type:application/x-www-form-urlencoded的头

    def post(self,request,*args,**kwargs):
        #获取解析后的结果
        print(request.data)
        return HttpResponse('paser')


###########################################序列化###########################################################

from rest_framework import serializers

#要先写一个序列化的类
class RolesSerializer(serializers.Serializer):
    #Role表里面的字段id和title序列化
    id = serializers.IntegerField()
    title = serializers.CharField()

class RolesView(APIView):
    def get(self,request,*args,**kwargs):
        # 方式一:对于[obj,obj,obj]
        # (Queryset)
        # roles = models.Role.objects.all()
        # 序列化,两个参数,instance:Queryset  如果有多个值,就需要加 mangy=True
        # ser = RolesSerializer(instance=roles,many=True)
        # 转成json格式,ensure_ascii=False表示显示中文,默认为True
        # ret = json.dumps(ser.data,ensure_ascii=False)

        # 方式二:
        role = models.Role.objects.all().first()
        ser = RolesSerializer(instance=role, many=False)
        ret = json.dumps(ser.data, ensure_ascii=False)
        return HttpResponse(ret)


# class UserInfoSerializer(serializers.Serializer):
#     '''序列化用户的信息'''
#     #user_type是choices(1,2,3),显示全称的方法用source
#     type = serializers.CharField(source="get_user_type_display")
#     username = serializers.CharField()
#     password = serializers.CharField()
#     #group.title:组的名字
#     group = serializers.CharField(source="group.title")
#     #SerializerMethodField(),表示自定义显示
#     #然后写一个自定义的方法
#     rls = serializers.SerializerMethodField()
#
#     def get_rls(self,row):
#         #获取用户所有的角色
#         role_obj_list = row.roles.all()
#         ret = []
#         #获取角色的id和名字
#         #以字典的键值对方式显示
#         for item in role_obj_list:
#             ret.append({"id":item.id,"title":item.title})
#         return ret


# class UserInfoSerializer(serializers.ModelSerializer):
#     type = serializers.CharField(source="get_user_type_display")
#     group = serializers.CharField(source="group.title")
#     rls = serializers.SerializerMethodField()
#
#     def get_rls(self, row):
#         # 获取用户所有的角色
#         role_obj_list = row.roles.all()
#         ret = []
#         # 获取角色的id和名字
#         # 以字典的键值对方式显示
#         for item in role_obj_list:
#             ret.append({"id": item.id, "title": item.title})
#         return ret
#
#     class Meta:
#         model = models.UserInfo
#         fields = ['id','username','password','type','group','rls']

# class UserInfoSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = models.UserInfo
#         #fields = "__all__"
#         fields = ['id','username','password','group','roles']
#         #表示连表的深度
#         depth = 1


class UserInfoSerializer(serializers.ModelSerializer):
    group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='pk')
    class Meta:
        model = models.UserInfo
        #fields = "__all__"
        fields = ['id','username','password','group','roles']
        #表示连表的深度
        depth = 0


class UserInfoView(APIView):
    '''用户的信息'''
    def get(self,request,*args,**kwargs):
        users = models.UserInfo.objects.all()
        #这里必须要传参数context={'request':request}
        ser = UserInfoSerializer(instance=users,many=True,context={'request':request})
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)


class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserGroup
        fields = "__all__"

class GroupView(APIView):
    def get(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        obj = models.UserGroup.objects.filter(pk=pk).first()

        ser = GroupSerializer(instance=obj,many=False)
        ret = json.dumps(ser.data,ensure_ascii=False)
        return HttpResponse(ret)



####################################序列化之用户请求数据验证验证####################################

#自定义验证规则
class GroupValidation(object):
    def __init__(self,base):
        self.base = base

    def __call__(self, value):
        if not value.startswith(self.base):
            message = "标题必须以%s为开头"%self.base
            raise serializers.ValidationError(message)


class UserGroupSerializer(serializers.Serializer):
    title = serializers.CharField(validators=[GroupValidation('以我开头'),])

class UserGroupView(APIView):
    def post(self,request,*args, **kwargs):
        ser = UserGroupSerializer(data=request.data)
        if ser.is_valid():
            print(ser.validated_data['title'])
        else:
            print(ser.errors)

        return HttpResponse("用户提交数据验证")


##################################################分页###################################################

from api.utils.serializsers.pager import PagerSerialiser
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination

# #自定义分页类1
# class MyPageNumberPagination(PageNumberPagination):
#     #每页显示多少个
#     page_size = 3
#     #默认每页显示3个,可以通过传入pager1/?page=2&size=4,改变默认每页显示的个数
#     page_size_query_param = "size"
#     #最大页数不超过10
#     max_page_size = 10
#     #获取页码数的
#     page_query_param = "page"

#自定义分页类2
class MyLimitOffsetPagination(LimitOffsetPagination):
    #默认显示的个数
    default_limit = 2
    #当前的位置
    offset_query_param = "offset"
    #通过limit改变默认显示的个数
    limit_query_param = "limit"
    #一页最多显示的个数
    max_limit = 10


#自定义分页类3 (加密分页)
class MyCursorPagination(CursorPagination):
    cursor_query_param = "cursor"
    page_size = 2     #每页显示2个数据
    ordering = 'id'   #排序
    page_size_query_param = None
    max_page_size = None


class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        #获取所有数据
        roles = models.Role.objects.all()
        #创建分页对象
        pg = MyCursorPagination()
        #获取分页的数据
        page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #对数据进行序列化
        ser = PagerSerialiser(instance=page_roles,many=True)
        return Response(ser.data)
        # return pg.get_paginated_response(ser.data)
# api/utils/serializsers/pager.py

from rest_framework import serializers
from api import models


class PagerSerialiser(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = "__all__"

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏恰童鞋骚年

自己动手写一个简单的MVC框架(第一版)

  路由(Route)、控制器(Controller)、行为(Action)、模型(Model)、视图(View)

16720
来自专栏大内老A

在ASP.NET MVC中通过URL路由实现对多语言的支持

对于一个需要支持多语言的Web应用,一个很常见的使用方式就是通过请求地址来控制界面呈现所基于的语言文化,比如我们在表示请求地址的URL中将上语言文化代码(比如e...

23360
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(30)-本地化(多语言)

我们的系统有时要扩展到其他国家,或者地区,需要更多的语言环境,微软提供了一些解决方案,原始我们是用js来控制的,现在不需要了。 我们只要创建简单的资源文件,通过...

35570
来自专栏大内老A

WCF版的PetShop之三:实现分布式的Membership和上下文传递

通过上一篇了解了模块内基本的层次划分之后,接下来我们来聊聊PetShop中一些基本基础功能的实现,以及一些设计、架构上的应用如何同WCF进行集成。本篇讨论两个问...

26750
来自专栏木宛城主

ASP.NET那点不为人知的事(一)

我们上网时,在浏览器地址输入网址,按下回车,一张网页就呈现在我们眼前。这究竟发生了什么?对于一名优秀的Programmer来说,我想有必要一下熟悉浏览器---...

40680
来自专栏柠檬先生

Angularjs基础(四)

AngularJS过滤器     过滤器可以使用一个管道符(|)添加到表达式和指令中。       AngularJS过滤器可用于转换数据:    ...

21390
来自专栏Ken的杂谈

C# MD5加密-MD5Helper

3.7K30
来自专栏大内老A

ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline - Part II

二、ASP.NET Runtime Pipeline(续ASP.NET Http Runtime Pipeline - Part I) 现在我们真正进入ASP....

21780
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(21)-权限管理系统-跑通整个系统

这一节我们来跑通整个系统,验证的流程,通过AOP切入方式,在访问方法之前,执行一个验证机制来判断是否有操作权限(如:增删改等) 原理:通过MVC自带筛选器,在筛...

78970
来自专栏linjinhe的专栏

LevelDB:使用介绍

Get 接口和 Put 接口比较像,除了 leveldb::ReadOptions 参数是用来控制读操作的,具体见链接指向的代码。

79350

扫码关注云+社区

领取腾讯云代金券