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 fileinput模块使用实例
Jun 03 Python
Python实现监控程序执行时间并将其写入日志的方法
Jun 30 Python
浅谈django model的get和filter方法的区别(必看篇)
May 23 Python
python3.4用函数操作mysql5.7数据库
Jun 23 Python
Python登录注册验证功能实现
Jun 18 Python
Django框架多表查询实例分析
Jul 04 Python
python的pytest框架之命令行参数详解(上)
Jun 27 Python
Pytorch 保存模型生成图片方式
Jan 10 Python
python实现提取str字符串/json中多级目录下的某个值
Feb 27 Python
Python处理mysql特殊字符的问题
Mar 02 Python
解决python便携版无法直接运行py文件的问题
Sep 01 Python
一文搞懂python异常处理、模块与包
Jun 26 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
使用PHP和XSL stylesheets转换XML文档
2006/10/09 PHP
PHP实现数据四舍五入的方法小结【4种方法】
2019/03/27 PHP
Javascript Jquery 遍历Json的实现代码
2010/03/31 Javascript
Extjs在exlipse中设置自动提示的方法
2010/04/07 Javascript
jquery.jstree 增加节点的双击事件代码
2010/07/27 Javascript
JS中的构造函数详细解析
2014/03/10 Javascript
nodejs中操作mysql数据库示例
2014/12/20 NodeJs
JavaScript数组去重的3种方法和代码实例
2015/07/01 Javascript
jQuery+PHP+MySQL二级联动下拉菜单实例讲解
2015/10/27 Javascript
为何JS操作的href都是javascript:void(0);呢
2015/11/12 Javascript
angular route中使用resolve在uglify压缩后问题解决
2016/09/21 Javascript
Node.js 使用request模块下载文件的实例
2018/09/05 Javascript
详解Vue 换肤方案验证
2019/08/28 Javascript
layui关闭层级、简单监听的实例
2019/09/06 Javascript
JS co 函数库的含义和用法实例总结
2020/04/08 Javascript
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
python实现ftp客户端示例分享
2014/02/17 Python
django 自定义用户user模型的三种方法
2014/11/18 Python
python利用正则表达式排除集合中字符的功能示例
2017/10/10 Python
Python将文本去空格并保存到txt文件中的实例
2018/07/24 Python
python实现三维拟合的方法
2018/12/29 Python
python 调用pyautogui 实时获取鼠标的位置、移动鼠标的方法
2019/08/27 Python
django Layui界面点击弹出对话框并请求逻辑生成分页的动态表格实例
2020/05/12 Python
python生成xml时规定dtd实例方法
2020/09/21 Python
HTML5+WebSocket实现多文件同时上传的实例
2016/12/29 HTML / CSS
Superdry极度干燥美国官网:英国制造的服装品牌
2018/11/13 全球购物
小学先进集体事迹材料
2014/05/31 职场文书
个人简历自荐信
2014/06/26 职场文书
普通党员对照检查材料
2014/08/28 职场文书
2014年评职称工作总结
2014/11/20 职场文书
会议开幕词
2015/01/28 职场文书
酒店服务员岗位职责
2015/02/09 职场文书
综合办公室主任岗位职责
2015/04/01 职场文书
2015年社区教育工作总结
2015/05/13 职场文书
办公经费申请报告
2015/05/15 职场文书
利用Pycharm连接服务器的全过程记录
2021/07/01 Python