Django rest framework实现分页的示例

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

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

(0)

相关推荐

  • Django自定义分页效果

    分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该显示在页面上的数据在数据库表中的起始位置. 确定分页需求: 1. 每页显示的数据条数 2. 每页显示页号链接数 3. 上一页和下一页 4. 首页和末页 效果图: 首先,利用django内置的分页功能,写分页类: from django.core.paginator import Paginator, Page # 导入django分页模块 class PageInfo(object): def __init__(self

  • django实现分页的方法

    本文实例讲述了django实现分页的方法.分享给大家供大家参考.具体如下: Python代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- # Create your views here. from django.shortcuts import render_to_response from winlog.log_dj.models import Winlog from django.core.paginator import Pagina

  • Django实现网页分页功能

    本文实例为大家分享了Django实现分页功能,为了容易区别功能的展现,先创建一个数据库,用数据库中的数据做演示. 创建数据库步骤如下: 1.创建模型,代码如下: from django.db import models # Create your models here. class Goods(models.Model): name = models.CharField(max_length=100) des = models.CharField(max_length=1000) class

  • Django分页查询并返回jsons数据(中文乱码解决方法)

    一.引子 Django 分页查询并返回 json ,需要将返回的 queryset 序列化, demo 如下: # coding=UTF-8 import os from django.core import serializers from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from django.shortcuts import render from django.http import

  • Django实现快速分页的方法实例

    前言 本文主要给大家介绍了关于Django快速分页的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 分页 在web开发中,对大量的商品进行分页显示,是常见的需求,django对分页直接提供了现成的函数,让我们的开发更为快速便捷... 动图_Django快速分页 示例代码: 在后端(视图函数中) from django.shortcuts import render from .models import ShowMyComputer # 引入方法 from djang

  • Django实现简单分页功能的方法详解

    本文实例讲述了Django实现简单分页功能的方法.分享给大家供大家参考,具体如下: 使用django的第三方模块django-pure-pagination 安装模块: pip install django-pure-pagination 将'pure_pagination'添加到settings.py文件中 INSTALLED_APPS = ( ... 'pure_pagination', ) 在view.py文件中 from django.shortcuts import render ro

  • Django自定义分页与bootstrap分页结合

    django中有自带的分页模块Paginator,想Paginator提供对象的列表,就可以提供每一页上对象的方法. 这里的话不讲解Paginator,而是自定义一个分页类来完成需求: class Pagination(object): """用于Model字段值的选择""" def __init__(self): pass @classmethod def create_pagination(self, from_name='', model_

  • Django的分页器实例(paginator)

    先导入模块: from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 分页器paginator 下面的所有方法: book_list=Book.objects.all() paginator = Paginator(book_list, 10) #实例化出一个对象 print("count:",paginator.count) #数据总数 print("num_pages",p

  • Django实现分页功能

    Django提供了一个新的类来帮助你管理分页数据,这个类存放在django/core/paginator.py.它可以接收列表.元组或其它可迭代的对象. class Paginator(object): def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True): self.object_list = object_list self.per_page = int(per_page) self

  • Django原生sql也能使用Paginator分页的示例代码

    django-pagination这是一个python包,来自github上的一个项目,很容易用. 不过这是一个懒人工具,好吧(工具理性).不过当一个页面有多处需要采用分页的话,就行不通了,要么修改django-pagination的源码,改变它的url指向,不过我没研究,当工程涉及到迁移时,要知道要安装各种东西本来就是个缺点,还要再修改源码,那就得不偿失.因而转战django自带的分页插件--Paginator. Paginator其实只需要实现两个方法`count`和`__getslice_

随机推荐