Django rest framework实现分页的示例


Posted in Python onMay 24, 2018

第一种分页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  #每页显示多少个
}

Django rest framework实现分页的示例

自定义分页类

#自定义分页类
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)

Django rest framework实现分页的示例

第二种分页 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)

Django rest framework实现分页的示例

Django rest framework实现分页的示例

返回的时候可以用get_paginated_response方法

自带上一页下一页

Django rest framework实现分页的示例

Django rest framework实现分页的示例

第三种分页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)

Django rest framework实现分页的示例

Django rest framework实现分页的示例

代码

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

# 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__"

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

Python 相关文章推荐
利用Python的Django框架中的ORM建立查询API
Apr 20 Python
Python 遍历子文件和所有子文件夹的代码实例
Dec 21 Python
python基础之入门必看操作
Jul 26 Python
浅析Python函数式编程
Oct 06 Python
python 统计一个列表当中的每一个元素出现了多少次的方法
Nov 14 Python
PyQt5 QTableView设置某一列不可编辑的方法
Jun 25 Python
python脚本之一键移动自定格式文件方法实例
Sep 02 Python
Pandas 解决dataframe的一列进行向下顺移问题
Dec 27 Python
通过实例解析Python return运行原理
Mar 04 Python
pycharm工具连接mysql数据库失败问题
Apr 01 Python
PyQt使用QPropertyAnimation开发简单动画
Apr 02 Python
Python 如何调试程序崩溃错误
Aug 03 Python
解决Matplotlib图表不能在Pycharm中显示的问题
May 24 #Python
Python系统监控模块psutil功能与经典用法分析
May 24 #Python
详解Django rest_framework实现RESTful API
May 24 #Python
matplotlib.pyplot画图 图片的二进制流的获取方法
May 24 #Python
matplotlib 输出保存指定尺寸的图片方法
May 24 #Python
Python简单获取网卡名称及其IP地址的方法【基于psutil模块】
May 24 #Python
在Django中输出matplotlib生成的图片方法
May 24 #Python
You might like
解决中英文字符串长度问题函数
2007/01/16 PHP
PHP使用in_array函数检查数组中是否存在某个值
2015/03/25 PHP
Discuz! 6.1_jQuery兼容问题
2008/09/23 Javascript
jQuery 使用手册(四)
2009/09/23 Javascript
JS setCapture 区域外事件捕捉
2010/03/18 Javascript
javascript下数值型比较难点说明
2010/06/07 Javascript
Tab页界面 用jQuery及Ajax技术实现(php后台)
2011/10/12 Javascript
js实现在文本框光标处添加字符的方法介绍
2012/11/24 Javascript
使用js对select动态添加和删除OPTION示例代码
2013/08/12 Javascript
基于javascript的JSON格式页面展示美化方法
2014/07/02 Javascript
jQuery提示插件alertify使用指南
2015/04/21 Javascript
利用Javascript实现简单的转盘抽奖
2017/02/13 Javascript
JQuery实现定时刷新功能代码
2017/05/09 jQuery
详解Vue.js基于$.ajax获取数据并与组件的data绑定
2017/05/26 Javascript
JavaScript递归算法生成树形菜单
2017/08/15 Javascript
JS实现导出Excel的五种方法详解【附源码下载】
2018/03/15 Javascript
基于VUE实现的九宫格抽奖功能
2018/09/30 Javascript
JS如何在数组指定位置插入元素
2020/03/10 Javascript
Vue Router中应用中间件的方法
2020/08/06 Javascript
JavaScript 实现继承的几种方式
2021/02/19 Javascript
[06:16]第十四期-国士无双绝地翻盘之撼地神牛
2014/06/24 DOTA
python选择排序算法的实现代码
2013/11/21 Python
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
Python科学计算包numpy用法实例详解
2018/02/08 Python
对Python 除法负数取商的取整方式详解
2018/12/12 Python
Python设计模式之模板方法模式实例详解
2019/01/17 Python
python脚本实现音频m4a格式转成MP3格式的实例代码
2019/10/09 Python
Python函数式编程指南:对生成器全面讲解
2019/11/19 Python
加拿大约会网站:EliteSingles.ca
2018/01/12 全球购物
物流管理专业毕业生自荐信
2014/03/04 职场文书
降消项目实施方案
2014/03/30 职场文书
《一个小村庄的故事》教学反思
2014/04/13 职场文书
工作检讨书怎么写
2015/01/23 职场文书
2015年农村党员干部主题教育活动总结
2015/03/25 职场文书
生日赠语
2015/06/23 职场文书
2016国庆节67周年红领巾广播稿
2015/12/18 职场文书