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 相关文章推荐
利用TensorFlow训练简单的二分类神经网络模型的方法
Mar 05 Python
python基础教程项目三之万能的XML
Apr 02 Python
python3安装pip3(install pip3 for python 3.x)
Apr 03 Python
Pandas:DataFrame对象的基础操作方法
Jun 07 Python
Python for循环中的陷阱详解
Jul 13 Python
Python实现基于POS算法的区块链
Aug 07 Python
在Pandas中处理NaN值的方法
Jun 25 Python
对Python3中列表乘以某一个数的示例详解
Jul 20 Python
python爬虫把url链接编码成gbk2312格式过程解析
Jun 08 Python
python中scipy.stats产生随机数实例讲解
Feb 19 Python
pandas取dataframe特定行列的实现方法
May 24 Python
利用Python实时获取steam特惠游戏数据
Jun 25 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 $_SERVER详解
2009/01/16 PHP
php结合安卓客户端实现查询交互实例
2015/05/05 PHP
Codeigniter中集成smarty和adodb的方法
2016/03/04 PHP
PHP笛卡尔积实现算法示例
2018/07/30 PHP
Js动态添加复选框Checkbox的实例方法
2013/04/08 Javascript
javascript一元操作符(递增、递减)使用示例
2013/08/07 Javascript
JavaScript识别网页关键字并进行描红的方法
2015/11/09 Javascript
javaScript给元素添加多个class的简单实现
2016/07/20 Javascript
thinkphp标签实现bootsrtap轮播carousel实例代码
2017/02/19 Javascript
微信小程序 登录的简单实现
2017/04/19 Javascript
node.js操作MongoDB的实例详解
2017/10/11 Javascript
CentOS7中源码编译安装NodeJS的完整步骤
2018/10/13 NodeJs
微信小程序时间戳转日期的详解
2019/04/30 Javascript
electron-vue开发环境内存泄漏问题汇总
2019/10/10 Javascript
小程序实现日历左右滑动效果
2019/10/21 Javascript
Vue中fragment.js使用方法小结
2020/02/17 Javascript
bootstrap-closable-tab可实现关闭的tab标签页插件
2020/08/09 Javascript
[01:10:02]IG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
浅谈python多线程和队列管理shell程序
2015/08/04 Python
python利用urllib和urllib2访问http的GET/POST详解
2017/09/27 Python
Python获取CPU、内存使用率以及网络使用状态代码
2018/02/08 Python
python opencv3实现人脸识别(windows)
2018/05/25 Python
Python自动发送邮件的方法实例总结
2018/12/08 Python
wxpython实现按钮切换界面的方法
2019/11/19 Python
如何更改 pandas dataframe 中两列的位置
2019/12/27 Python
python 使用elasticsearch 实现翻页的三种方式
2020/07/31 Python
美国新蛋IT数码商城:Newegg.com
2016/07/21 全球购物
美国领先的汽车轮胎和轮毂供应商:TireBuyer
2016/07/21 全球购物
贝嫂喜欢的婴儿品牌,个性化的婴儿礼物:My 1st Years
2017/11/19 全球购物
会话Bean的种类
2013/11/07 面试题
绘画设计学生的个人自我评价
2013/09/20 职场文书
通信工程毕业生自荐信
2013/11/01 职场文书
幼儿园庆六一游园活动方案
2014/01/29 职场文书
志愿者活动总结
2014/04/28 职场文书
献爱心捐款倡议书
2014/05/14 职场文书
企业法人代表任命书
2014/06/06 职场文书