RESTful-rest_framework版本控制、分页器-第六篇
版本控制:
源码位置分析第一步:
源码位置分析第二步:在APIView-despath方法-initial-determine_version
#执行determine_version,返回两个值,放到request对象里 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme def determine_version(self, request, *args, **kwargs): #当配置上版本类之后,就会实例化 if self.versioning_class is None: return (None, None) scheme = self.versioning_class() return (scheme.determine_version(request, *args, **kwargs), scheme)
代码实现:
settings配置
REST_FRAMEWORK={ # 'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer'], #url中获取值的key 'VERSION_PARAM':'version', #默认版本(从request对象里取不到,显示的默认值版本号,例如:默认不写后台打印也是v2 http://127.0.0.1:8006/testversion/) 'DEFAULT_VERSION':'v2', #允许的版本(只有写在列表里面的,浏览器访问才能输入响应的版本地址,例如:http://127.0.0.1:8006/v2/testversion/) 'ALLOWED_VERSIONS':['v1','v2']
路由设置:
#对应视图方式一:
url(r'^testversion/', views.Test.as_view()),
#对应视图方式二: url(r'^(?P<version>[v1|v2|v3]+)/testversion/', views.Test2.as_view(),name='ttt'),
视图设置:
from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning #情况一: class Test(APIView): #不再是列表 versioning_class=QueryParameterVersioning def get(self,request,*args,**kwargs): print(request.version) #v2 return Response('ok') #情况二: from django.urls import reverse class Test2(APIView):
#不再是列表 versioning_class=URLPathVersioning def get(self,request,*args,**kwargs):
#获取版本 print(request.version) #v1
#获取版本管理的类 print(request.versioning_scheme)
#反向生成url url=request.versioning_scheme.reverse(viewname='ttt',request=request) print(url) #http://127.0.0.1:8006/v1/testversion/ url2=reverse(viewname='ttt',kwargs={'version':'v1'}) print(url2) #/v1/testversion/ return Response('ok ttest2')
分页器:
路由:
url(r'^page', views.Page.as_view()),
BookSer序列化所有书籍:
class BookSer(serializers.ModelSerializer): class Meta: model=models.Book fields='__all__'
一 简单分页(查看第n页,每页显示n条)
1 简单分页 http://127.0.0.1:8006/page/?page=2&size=4 PageNumberPagination #每页显示多少条api_settings.PAGE_SIZE #page_size = #查询指定页码的参数 #page_query_param = 'page' #指定每页显示条数 #page_size_query_param = None #限制每页显示最大条数 #max_page_size = None
#简单分页:PageNumberPagination from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination class Page(APIView): def get(self,request,*args,**kwargs): #获取所有数据 ret=models.Book.objects.all() #创建分页对象 my_page=PageNumberPagination() #默认每页显示条数 my_page.page_size=2 #指定每页显示条数(受下面最大显示条数的限制) my_page.page_size_query_param='size' #限制每页最大显示条数 my_page.max_page_size=5 #在数据库中获取分页数据 page_list=my_page.paginate_queryset(ret,request,self) #对分页进行实例化 ser=BookSer(instance=page_list,many=True) # 1 再setting里配置每页条数 # 2 写一个类,继承它,属性重写 # 3 再对象里修改 ''' 每页显示多少条api_settings.PAGE_SIZE page_size = 查询指定页码的参数 page_query_param = 'page' 指定每页显示条数 page_size_query_param = None 限制每页显示最大条数 max_page_size = None ''' return Response(ser.data)
图解:
二 偏移分页(在第n个位置,向后查看n条数据)
偏移分页要点: 后台返回的url:http://127.0.0.1:8006/page?limit=3&offset=2 LimitOffsetPagination default_limit:默认显示多少条 max_limit:最大显示多少条 limit_query_param:重新命名limit(limit=4:表明显示四条,受max_limit的限制) offset_query_param:指定查询的标杆名(offset=1:表明从第二条开始,往后偏移)
#偏移分页:LimitOffsetPagination # 也可以自定制,同简单分页 class Page(APIView): def get(self,request,*args,**kwargs): #获取所有数据 ret=models.Book.objects.all() #创建分页而对象 my_page=LimitOffsetPagination() my_page.default_limit=3 my_page.max_limit=5 #在数据库中获取分页的数据 page_list=my_page.paginate_queryset(ret,request,self) #对分页进行序列化 ser=BookSer(instance=page_list,many=True) # 1 再setting里配置每页条数 # 2 写一个类,继承它,属性重写 # 3 再对象里修改 ''' default_limit:默认显示多少条 max_limit:最大显示多少条 limit_query_param:重新命名limit(limit=4:表明显示四条,受max_limit的限制) offset_query_param:指定查询的标杆名(offset=1:表明从第二条开始,往后偏移) ''' #只是显示指定访问的内容(不包含总条数和上、下页链接) # return Response(ser.data) # 对Response做了封装,返回内容里有总条数,上一页,下一页的链接 return my_page.get_paginated_response(ser.data)
图解:
三 加密分页:CursorPagination(只能看上一页和下一页,速度快)
加密分页要点: 后台返回的url:例如 http://127.0.0.1:8006/page?cursor=cD0y(随机的字符串) CursorPagination cursor_query_param = 'cursor':查询的名字 page_size = api_settings.PAGE_SIZE:每页显示的条数 ordering = '-created' :按谁排序
#加密分页:CursorPagination #看源码,是通过sql查询,大于id和小于id class Page(APIView): def get(self,request,*args,**kwargs): #获取所有数据 ret=models.Book.objects.all() #创建分页对象 my_page=CursorPagination() #安装id就行排序 my_page.ordering='id' #限制每页显示的条数 my_page.page_size=2 page_list=my_page.paginate_queryset(ret,request,self) ser=BookSer(instance=page_list,many=True) # 1 再setting里配置每页条数 # 2 写一个类,继承它,属性重写 # 3 再对象里修改 ''' cursor_query_param = 'cursor':查询的名字(即浏览器后面跟的名字例如:http://127.0.0.1:8006/page?cursor=cD0y) page_size = api_settings.PAGE_SIZE:每页显示的条数 ordering = '-created' :按谁排序 #浏览器验证: #1.http://127.0.0.1:8006/page 首先打开显示2条数据 #2.http://127.0.0.1:8006/page?cursor=cj0xJnA9NQ%3D%3D ''' # return Response(ser.data) # 对Response做了封装,返回内容里有总条数,上一页,下一页的链接(可避免页面被猜到) return my_page.get_paginated_response(ser.data) #作用就是打印首页会有上一个和下一页的链接,如下备注 # return Response(ser.data) '''可以手动点击上、下翻页(看不到页码) "next": "http://127.0.0.1:8006/page?cursor=cD00", "previous": "http://127.0.0.1:8006/page?cursor=cj0xJnA9Mw%3D%3D", ... '''
访问效果图: