python

超轻量级php框架startmvc

Django rest framework实现分页的示例

更新时间:2020-06-03 08:54:01 作者:startmvc
第一种分页PageNumberPagination基本使用(1)urls.pyurlpatterns=[re_path('(?P<version>[v1|v2]+)/page1

第一种分页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__"

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

Django rest framework 分页