欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django rest framework实现分页的示例

程序员文章站 2022-03-22 12:35:53
第一种分页pagenumberpagination 基本使用 (1)urls.py urlpatterns = [ re_path('(?p&l...

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

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