侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Django rest framework实现分页的示例

框架(架构)  /  管理员 发布于 7年前   194

第一种分页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.pyfrom rest_framework import serializersfrom api import modelsclass PagerSerialiser(serializers.ModelSerializer):  class Meta:    model = models.Role    fields = "__all__"

(3)views.py

from api.utils.serializsers.pager import PagerSerialiserfrom rest_framework.response import Responsefrom rest_framework.pagination import PageNumberPaginationclass 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

自定义

#自定义分页类2class MyLimitOffsetPagination(LimitOffsetPagination):  #默认显示的个数  default_limit = 2  #当前的位置  offset_query_param = "offset"  #通过limit改变默认显示的个数  limit_query_param = "limit"  #一页最多显示的个数  max_limit = 10class 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 = Noneclass 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.pyfrom django.contrib import adminfrom django.urls import path,includeurlpatterns = [  #path('admin/', admin.site.urls),  path('api/',include('api.urls') ),]
# api/urls.pyfrom django.urls import path,re_pathfrom .views import UserView,PaserView,RolesView,UserInfoView,GroupView,UserGroupViewfrom .views import Pager1Viewurlpatterns = [  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.pyfrom django.db import modelsclass 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.pyimport jsonfrom django.shortcuts import render,HttpResponsefrom rest_framework.views import APIViewfrom rest_framework.request import Requestfrom rest_framework.versioning import URLPathVersioningfrom . 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,FormParserclass 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 = 1class 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 = 0class 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 PagerSerialiserfrom rest_framework.response import Responsefrom 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"#自定义分页类2class 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 = Noneclass 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.pyfrom rest_framework import serializersfrom api import modelsclass PagerSerialiser(serializers.ModelSerializer):  class Meta:    model = models.Role    fields = "__all__"

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


  • 上一条:
    Django使用HttpResponse返回图片并显示的方法
    下一条:
    详解Django rest_framework实现RESTful API
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客