Django rest framework實(shí)現(xiàn)分頁(yè)的示例
第一種分頁(yè)P(yáng)ageNumberPagination
基本使用
(1)urls.py
urlpatterns = [ re_path('(?P<version>[v1|v2]+)/page1/', Pager1View.as_view(),) #分頁(yè)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): #獲取所有數(shù)據(jù) roles = models.Role.objects.all() #創(chuàng)建分頁(yè)對(duì)象 pg = PageNumberPagination() #獲取分頁(yè)的數(shù)據(jù) page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self) #對(duì)數(shù)據(jù)進(jìn)行序列化 ser = PagerSerialiser(instance=page_roles,many=True) return Response(ser.data)
(4)settings配置
REST_FRAMEWORK = { #分頁(yè) "PAGE_SIZE":2 #每頁(yè)顯示多少個(gè) }
自定義分頁(yè)類(lèi)
#自定義分頁(yè)類(lèi) class MyPageNumberPagination(PageNumberPagination): #每頁(yè)顯示多少個(gè) page_size = 3 #默認(rèn)每頁(yè)顯示3個(gè),可以通過(guò)傳入pager1/?page=2&size=4,改變默認(rèn)每頁(yè)顯示的個(gè)數(shù) page_size_query_param = "size" #最大頁(yè)數(shù)不超過(guò)10 max_page_size = 10 #獲取頁(yè)碼數(shù)的 page_query_param = "page" class Pager1View(APIView): def get(self,request,*args,**kwargs): #獲取所有數(shù)據(jù) roles = models.Role.objects.all() #創(chuàng)建分頁(yè)對(duì)象,這里是自定義的MyPageNumberPagination pg = MyPageNumberPagination() #獲取分頁(yè)的數(shù)據(jù) page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self) #對(duì)數(shù)據(jù)進(jìn)行序列化 ser = PagerSerialiser(instance=page_roles,many=True) return Response(ser.data)
第二種分頁(yè) LimitOffsetPagination
自定義
#自定義分頁(yè)類(lèi)2 class MyLimitOffsetPagination(LimitOffsetPagination): #默認(rèn)顯示的個(gè)數(shù) default_limit = 2 #當(dāng)前的位置 offset_query_param = "offset" #通過(guò)limit改變默認(rèn)顯示的個(gè)數(shù) limit_query_param = "limit" #一頁(yè)最多顯示的個(gè)數(shù) max_limit = 10 class Pager1View(APIView): def get(self,request,*args,**kwargs): #獲取所有數(shù)據(jù) roles = models.Role.objects.all() #創(chuàng)建分頁(yè)對(duì)象 pg = MyLimitOffsetPagination() #獲取分頁(yè)的數(shù)據(jù) page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self) #對(duì)數(shù)據(jù)進(jìn)行序列化 ser = PagerSerialiser(instance=page_roles,many=True) return Response(ser.data)
返回的時(shí)候可以用get_paginated_response方法
自帶上一頁(yè)下一頁(yè)
第三種分頁(yè)CursorPagination
加密分頁(yè)方式,只能通過(guò)點(diǎn)“上一頁(yè)”和下一頁(yè)訪(fǎng)問(wèn)數(shù)據(jù)
#自定義分頁(yè)類(lèi)3 (加密分頁(yè)) class MyCursorPagination(CursorPagination): cursor_query_param = "cursor" page_size = 2 #每頁(yè)顯示2個(gè)數(shù)據(jù) ordering = 'id' #排序 page_size_query_param = None max_page_size = None class Pager1View(APIView): def get(self,request,*args,**kwargs): #獲取所有數(shù)據(jù) roles = models.Role.objects.all() #創(chuàng)建分頁(yè)對(duì)象 pg = MyCursorPagination() #獲取分頁(yè)的數(shù)據(jù) page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self) #對(duì)數(shù)據(jù)進(jìn)行序列化 ser = PagerSerialiser(instance=page_roles,many=True) # return Response(ser.data) return pg.get_paginated_response(ser.data)
代碼
版本、解析器、序列化和分頁(yè)
# 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(),), #序列化做驗(yàn)證 re_path('(?P<version>[v1|v2]+)/pager1/', Pager1View.as_view(),) #分頁(yè)1 ]
# api/models.py from django.db import models class UserInfo(models.Model): USER_TYPE = ( (1,'普通用戶(hù)'), (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) #獲取處理版本的對(duì)象 print(request.versioning_scheme) #獲取瀏覽器訪(fǎng)問(wèn)的url,reverse反向解析 #需要兩個(gè)參數(shù):viewname就是url中的別名,request=request是url中要傳入的參數(shù) #(?P<version>[v1|v2]+)/users/,這里本來(lái)需要傳version的參數(shù),但是version包含在request里面,所有只需要request=request就可以 url_path = request.versioning_scheme.reverse(viewname='api_user',request=request) print(url_path) self.dispatch return HttpResponse('用戶(hù)列表') # 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): #獲取解析后的結(jié)果 print(request.data) return HttpResponse('paser') ###########################################序列化########################################################### from rest_framework import serializers #要先寫(xiě)一個(gè)序列化的類(lèi) class RolesSerializer(serializers.Serializer): #Role表里面的字段id和title序列化 id = serializers.IntegerField() title = serializers.CharField() class RolesView(APIView): def get(self,request,*args,**kwargs): # 方式一:對(duì)于[obj,obj,obj] # (Queryset) # roles = models.Role.objects.all() # 序列化,兩個(gè)參數(shù),instance:Queryset 如果有多個(gè)值,就需要加 mangy=True # ser = RolesSerializer(instance=roles,many=True) # 轉(zhuǎn)成json格式,ensure_ascii=False表示顯示中文,默認(rèn)為T(mén)rue # 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): # '''序列化用戶(hù)的信息''' # #user_type是choices(1,2,3),顯示全稱(chēng)的方法用source # type = serializers.CharField(source="get_user_type_display") # username = serializers.CharField() # password = serializers.CharField() # #group.title:組的名字 # group = serializers.CharField(source="group.title") # #SerializerMethodField(),表示自定義顯示 # #然后寫(xiě)一個(gè)自定義的方法 # rls = serializers.SerializerMethodField() # # def get_rls(self,row): # #獲取用戶(hù)所有的角色 # role_obj_list = row.roles.all() # ret = [] # #獲取角色的id和名字 # #以字典的鍵值對(duì)方式顯示 # 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): # # 獲取用戶(hù)所有的角色 # role_obj_list = row.roles.all() # ret = [] # # 獲取角色的id和名字 # # 以字典的鍵值對(duì)方式顯示 # 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): '''用戶(hù)的信息''' def get(self,request,*args,**kwargs): users = models.UserInfo.objects.all() #這里必須要傳參數(shù)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) ####################################序列化之用戶(hù)請(qǐng)求數(shù)據(jù)驗(yàn)證驗(yàn)證#################################### #自定義驗(yàn)證規(guī)則 class GroupValidation(object): def __init__(self,base): self.base = base def __call__(self, value): if not value.startswith(self.base): message = "標(biāo)題必須以%s為開(kāi)頭"%self.base raise serializers.ValidationError(message) class UserGroupSerializer(serializers.Serializer): title = serializers.CharField(validators=[GroupValidation('以我開(kāi)頭'),]) 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("用戶(hù)提交數(shù)據(jù)驗(yàn)證") ##################################################分頁(yè)################################################### from api.utils.serializsers.pager import PagerSerialiser from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination # #自定義分頁(yè)類(lèi)1 # class MyPageNumberPagination(PageNumberPagination): # #每頁(yè)顯示多少個(gè) # page_size = 3 # #默認(rèn)每頁(yè)顯示3個(gè),可以通過(guò)傳入pager1/?page=2&size=4,改變默認(rèn)每頁(yè)顯示的個(gè)數(shù) # page_size_query_param = "size" # #最大頁(yè)數(shù)不超過(guò)10 # max_page_size = 10 # #獲取頁(yè)碼數(shù)的 # page_query_param = "page" #自定義分頁(yè)類(lèi)2 class MyLimitOffsetPagination(LimitOffsetPagination): #默認(rèn)顯示的個(gè)數(shù) default_limit = 2 #當(dāng)前的位置 offset_query_param = "offset" #通過(guò)limit改變默認(rèn)顯示的個(gè)數(shù) limit_query_param = "limit" #一頁(yè)最多顯示的個(gè)數(shù) max_limit = 10 #自定義分頁(yè)類(lèi)3 (加密分頁(yè)) class MyCursorPagination(CursorPagination): cursor_query_param = "cursor" page_size = 2 #每頁(yè)顯示2個(gè)數(shù)據(jù) ordering = 'id' #排序 page_size_query_param = None max_page_size = None class Pager1View(APIView): def get(self,request,*args,**kwargs): #獲取所有數(shù)據(jù) roles = models.Role.objects.all() #創(chuàng)建分頁(yè)對(duì)象 pg = MyCursorPagination() #獲取分頁(yè)的數(shù)據(jù) page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self) #對(duì)數(shù)據(jù)進(jìn)行序列化 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__"
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)對(duì)excel文件列表值進(jìn)行統(tǒng)計(jì)的方法
這篇文章主要介紹了Python實(shí)現(xiàn)對(duì)excel文件列表值進(jìn)行統(tǒng)計(jì)的方法,涉及Python基于win32com組件操作表格文件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07Python實(shí)現(xiàn)識(shí)別文字中的省市區(qū)并繪圖
在做NLP(自然語(yǔ)言處理)相關(guān)任務(wù)時(shí),經(jīng)常會(huì)遇到需要識(shí)別并提取省、城市、行政區(qū)的需求。今天給大家介紹一個(gè)模塊,你只需要把字符串傳遞給這個(gè)模塊,他就能給你返回這個(gè)字符串內(nèi)的省、市、區(qū)關(guān)鍵詞,快來(lái)學(xué)習(xí)一下吧2022-06-06Python基于tkinter canvas實(shí)現(xiàn)圖片裁剪功能
這篇文章主要介紹了Python基于tkinter canvas實(shí)現(xiàn)圖片裁剪功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11python爬蟲(chóng)Scrapy框架:媒體管道原理學(xué)習(xí)分析
這篇文章主要介紹了python爬蟲(chóng)Scrapy框架:媒體管道原理學(xué)習(xí)分析,有需要的朋友可以借鑒參考,希望可以對(duì)廣大一同學(xué)習(xí)的讀者朋友有所幫助2021-09-09解決PySide+Python子線(xiàn)程更新UI線(xiàn)程的問(wèn)題
今天小編就為大家分享一篇解決PySide+Python子線(xiàn)程更新UI線(xiàn)程的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Python+Socket實(shí)現(xiàn)基于UDP協(xié)議的局域網(wǎng)廣播功能示例
這篇文章主要介紹了Python+Socket實(shí)現(xiàn)基于UDP協(xié)議的局域網(wǎng)廣播功能,結(jié)合實(shí)例形式分析了Python+socket實(shí)現(xiàn)UDP協(xié)議廣播的客戶(hù)端與服務(wù)器端功能相關(guān)操作技巧,需要的朋友可以參考下2017-08-08詳解Numpy中的數(shù)組拼接、合并操作(concatenate, append, stack, hstack, vstac
這篇文章主要介紹了詳解Numpy中的數(shù)組拼接、合并操作(concatenate, append, stack, hstack, vstack, r_, c_等),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05