1、分頁
試問若是當數據量特別大的時候,你是怎麼解決分頁的?html
- 方式a、記錄當前訪問頁數的數據id
- 方式b、最多顯示120頁等
- 方式c、只顯示上一頁,下一頁,不讓選擇頁碼,對頁碼進行加密
一、基於limit offset 作分頁python
from rest_framework.pagination import LimitOffsetPagination
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/(?P<version>[v1|v2]+)/', include('app01.urls')) ]
app01.urlweb
urlpatterns = [ url(r'^index1/', views.IndexView1.as_view()), url(r'^index2/', views.IndexView2.as_view()), url(r'^index3/', views.IndexView3.as_view()), url(r'^index4/', views.IndexView4.as_view()), url(r'^index5/', views.IndexView5.as_view()), ]
views.py數據庫
from rest_framework.views import APIView from rest_framework.response import Response from app01.serializes.myserializes import MySerializes from rest_framework.pagination import LimitOffsetPagination from app01 import models # =========== 能夠本身進行自定製分頁,基於limitoffset=================== class P1(LimitOffsetPagination): max_limit = 3 # 最大限制默認是None default_limit =2 # 設置每一頁顯示多少條 limit_query_param = 'limit' # 日後取幾條 offset_query_param = 'offset' # 當前所在的位置 class IndexView2(APIView): #使用http://127.0.0.1:8080/app01/v1/index2/?offset=2&limit=4可進行判斷 def get(self,request,*args,**kwargs): user_list = models.UserInfo.objects.all() p1 = P1()#註冊分頁 page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self) print('打印的是分頁的數據',page_user_list) ser = MySerializes(instance=page_user_list,many=True) #可容許多個 # return Response(ser.data) #不含上一頁下一頁 return p1.get_paginated_response(ser.data) =======================也能夠用下面這種形式=========== class BaseResponse(object): def __init__(self,code=1000,data=None,error=None): self.code = code self.data = data self.error = error class IndexView(views.APIView): '''第二種類表示的方式''' def get(self,request,*args,**kwargs): ret = BaseResponse() try: user_list = models.UserInfo.objects.all() p1 = P1() page_user_list = p1.paginate_queryset(queryset=user_list,request=request,view=self) ser = IndexSerializer(instance=page_user_list,many=True) ret.data = ser.data ret.next = p1.get_next_link() except Exception as e: ret.code= 1001 ret.error = 'xxxx錯誤' return Response(ret.__dict__)
二、基於頁碼的分頁django
from rest_framework.pagination import PageNumberPagination
# ======================基於頁碼實現的分頁============== class P2(PageNumberPagination): #默認每頁顯示的數據條數 page_size = 2 #獲取url參數中設置的每頁顯示數據條數 page_size_query_param = 'size' #獲取url中傳入的頁碼key page_query_param = 'page' #最大支持的每頁顯示的數據條數 max_page_size = 5 class IndexView3(APIView): #使用http://127.0.0.1:8080/app01/v1/index3/?page=1&page_size=1可進行判斷 def get(self,request,*args,**kwargs): user_list = models.UserInfo.objects.all() #實例化分頁對象,獲取數據庫中的分頁數據 p2 = P2() print(p2.page_size_query_description) page_user_list = p2.paginate_queryset(queryset=user_list,request=request,view=self) print('打印的是分頁的數據',page_user_list) #序列化對象 ser = MySerializes(instance=page_user_list,many=True) #可容許多個 #生成分頁和數據 # return Response(ser.data) #不含上一頁下一頁 return p2.get_paginated_response(ser.data)
三、基於Cursor的分頁json
2可能存在性能問題,若是用戶吧page給改的很大,查詢速度就會很慢。還有一種頁碼加密的方式,api
# =====================基於Cursor的分頁============ class P3(CursorPagination): # URL傳入的遊標參數 cursor_query_param = 'cursor' # 默認每頁顯示的數據條數 page_size = 2 # URL傳入的每頁顯示條數的參數 page_size_query_param = 'size' # 每頁顯示數據最大條數 max_page_size = 3 # 根據ID從大到小排列 ordering = "id" class IndexView4(APIView): #使用http://127.0.0.1:8080/app01/v1/index4/?cursor=cj0xJnA9NA%3D%3D&size=3可進行判斷 def get(self,request,*args,**kwargs): user_list = models.UserInfo.objects.all().order_by('-id') p3 = P3()#註冊分頁 page_user_list = p3.paginate_queryset(queryset=user_list,request=request,view=self) print('打印的是分頁的數據',page_user_list) ser = MySerializes(instance=page_user_list,many=True) #可容許多個 # return Response(ser.data) #不含上一頁下一頁 return p3.get_paginated_response(ser.data)
2、視圖
寫視圖函數可繼承的幾個類,咱們之前常常用到的是APIView,如今咱們來了解一下其餘的類,其中一、三、4用到的最多瀏覽器
須要導入的類app
from rest_framework.views import APIView from rest_framework.generics import GenericAPIView from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import ModelViewSet
一、APIView函數
class IndexView2(APIView): def get(self,request,*args,**kwargs): user_list = models.UserInfo.objects.all() ser = MySerializes(instance=user_list,many=True) return Response(ser.data)
二、GenericAPIView(APIView)
from rest_framework.response import Response from rest_framework.generics import GenericAPIView from app01 import models from app01.serializes.myserializes import MySerializes from rest_framework.pagination import LimitOffsetPagination class P1(LimitOffsetPagination): max_limit = 3 # 最大限制默認是None default_limit =2 # 設置每一頁顯示多少條 limit_query_param = 'limit' # 日後取幾條 offset_query_param = 'offset' # 當前所在的位置 class IndexView1(GenericAPIView): queryset = models.UserInfo.objects.all() serializer_class = MySerializes pagination_class = P1 def get(self,request,*args,**kwargs): user_list = self.get_queryset() p1 = P1() #註冊分頁 data = p1.paginate_queryset(queryset=user_list,request=request,view=self) #獲取分頁的數據 ser = self.get_serializer(instance=data,many=True) #序列化 return Response(ser.data)
三、 GenericViewSet(ViewSetMixin, generics.GenericAPIView)
增 POST /users/ 刪 DELETE /users/1/ 改 #所有修改 PUT /users/1/ #局部修改 patch /users/1/ 查 GET /users/ GET /users/1/
在GET請求的時候若是帶ID說明查一條,若是不帶則查全部
原始的
urlpatterns = [ url(r'^index/$', views.IndexView.as_view()), url(r'^index/(?P<pk>\d+)$', views.IndexView.as_view()), ]
class IndexView(views.APIView): def get(self,request,*args,**kwargs): pk = kwargs.get('pk') if pk: pass # 獲取單條信息 else: pass # 獲取列表信息 def post(self,request,*args,**kwargs): pass def put(self,request,*args,**kwargs): pass def patch(self,request,*args,**kwargs): pass def delete(self,request,*args,**kwargs): pass
用了GenericViewSet這種方式的時候注意url變了
urlpatterns = [ url(r'^index3/$', views.IndexView3.as_view({'get': 'list','post':'create'})), url(r'^index3/(?P<pk>\d+)/$', views.IndexView3.as_view({'get':'retrieve'})), ]
class IndexView3(GenericViewSet): queryset = models.UserInfo.objects.all() serializer_class = MySerializes pagination_class = P1 def list(self,request,*args,**kwargs): #獲取列表信息 return Response('...') def retrieve(self,request,*args,**kwargs): #獲取單條數據 return Response('xxx')
四、 ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet)
利用ModelViewSet增刪改查不用本身寫了,內部把增刪改查都幹了,當知足不了需求的時候咱們也能夠自定製
urlpatterns = [ url(r'^index4/', views.IndexView4.as_view({'get': 'list','post':'create'})), #獲取數據和添加數據 url(r'^index4\.(?P<format>[a-z0-9]+)/', views.IndexView4.as_view({'get': 'list','post':'create'})), #.json想讓頁面上顯示成json格式 url(r'^index4/(?P<pk>\d+)/', views.IndexView4.as_view({'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})), #查看單條,刪除,修改數據 url(r'^index4(?P<pk>\d+)\.(?P<format>[a-z0-9]+)/', views.IndexView4.as_view({'get': 'retrieve', 'delete': 'destroy','put':'partial_update'})), ]
注意啦:用ModelSerializer這種方法必需要用IndexSerializer(ModelSerializer)這種方式序列化 class P2(PageNumberPagination): page_size = 3 #每一頁顯示的條數 page_query_param = 'page' #獲取參數中傳入的頁碼 page_size_query_param = 'size' #獲取url參數中每頁顯示的數據條數 max_page_size = 5 class IndexSerializer(ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class IndexView4(ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = IndexSerializer pagination_class = P2
自定製
class P2(PageNumberPagination): page_size = 3 #每一頁顯示的條數 page_query_param = 'page' #獲取參數中傳入的頁碼 page_size_query_param = 'size' #獲取url參數中每頁顯示的數據條數 max_page_size = 5 class IndexSerializer(ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class IndexView4(ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = IndexSerializer pagination_class = P2 def list(self, request, *args, **kwargs): '''獲取get請求的全部''' pass def retrieve(self, request, *args, **kwargs): '''查看單條數據''' pass def destroy(self, request, *args, **kwargs): '''刪除DELETE''' pass def create(self, request, *args, **kwargs): '''添加數據POST''' pass def update(self, request, *args, **kwargs): '''所有修改PUT''' pass def partial_update(self, request, *args, **kwargs): '''局部修改PATCH''' pass
繼承關係
3、路由
第一類:自定義路由
# http://127.0.0.1:8000/api/v1/auth/ url(r'^auth/$', views.AuthView.as_view()), # http://127.0.0.1:8000/api/v1/auth.json # 想要讓頁面顯示json格式 url(r'^auth\.(?P<format>[a-z0-9]+)$', views.AuthView.as_view()), # http://127.0.0.1:8000/api/v1/auth/1/ url(r'^auth/(?P<pk>\d+)/$', views.AuthView.as_view()), # http://127.0.0.1:8000/api/v1/auth/1.json url(r'^auth/(?P<pk>\d+)\.(?P<format>[a-z0-9]+)$', views.AuthView.as_view()), class AuthView(views.APIView): def get(self,request,*args,**kwargs): return Response('...')
第二類:半自動路由
url(r'^index/$', views.IndexView.as_view({'get':'list','post':'create'})), url(r'^index\.(?P<format>[a-z0-9]+)$', views.IndexView.as_view({'get':'list','post':'create'})), url(r'^index/(?P<pk>\d+)/$', views.IndexView.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})), url(r'^index(?P<pk>\d+)\.(?P<format>[a-z0-9]+)$', views.IndexView.as_view({'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})), class IndexView(viewsets.ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = IndexSerializer pagination_class = P2
第三類:全自動路由,會自動生成四個url
router = DefaultRouter() router.register('index',views.IndexViewSet) urlpatterns = [ url(r'^', include(router.urls)), ] class IndexViewSet(viewsets.ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = IndexSerializer pagination_class = P2 class IndexSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__"
4、渲染器
根據 用戶請求URL 或 用戶可接受的類型,篩選出合適的 渲染組件。
用戶請求URL:
- http://127.0.0.1:8000/test/?format=json
- http://127.0.0.1:8000/test.json
用戶請求頭:
- Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
一、. json
訪問URL:
- http://127.0.0.1:8000/test/?format=json
- http://127.0.0.1:8000/test.json
- http://127.0.0.1:8000/test/
from django.conf.urls import url, include from web.views import s11_render urlpatterns = [ url(r'^test/$', s11_render.TestView.as_view()), url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()), ] urls.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from rest_framework.renderers import JSONRenderer from .. import models class TestSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class TestView(APIView): renderer_classes = [JSONRenderer, ] def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all() ser = TestSerializer(instance=user_list, many=True) return Response(ser.data)
二、.表格
訪問URL:
- http://127.0.0.1:8000/test/?format=admin
- http://127.0.0.1:8000/test.admin
- http://127.0.0.1:8000/test/
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from rest_framework.renderers import AdminRenderer from .. import models class TestSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class TestView(APIView): renderer_classes = [AdminRenderer, ] def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all() ser = TestSerializer(instance=user_list, many=True) return Response(ser.data)
三、 Form表單
訪問URL:
- http://127.0.0.1:8000/test/?format=form
- http://127.0.0.1:8000/test.form
- http://127.0.0.1:8000/test/
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from rest_framework.renderers import JSONRenderer from rest_framework.renderers import AdminRenderer from rest_framework.renderers import HTMLFormRenderer from .. import models class TestSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class TestView(APIView): renderer_classes = [HTMLFormRenderer, ] def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all().first() ser = TestSerializer(instance=user_list, many=False) return Response(ser.data)
四、 自定義顯示模板
訪問URL:
- http://127.0.0.1:8000/test/?format=html
- http://127.0.0.1:8000/test.html
- http://127.0.0.1:8000/test/
from django.conf.urls import url, include from web.views import s11_render urlpatterns = [ url(r'^test/$', s11_render.TestView.as_view()), url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()), ]
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from rest_framework.renderers import TemplateHTMLRenderer from .. import models class TestSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class TestView(APIView): renderer_classes = [TemplateHTMLRenderer, ] def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all().first() ser = TestSerializer(instance=user_list, many=False) return Response(ser.data, template_name='user_detail.html')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{ user }} {{ pwd }} {{ ut }} </body> </html>
五、瀏覽器格式API+JSON
訪問URL:
- http://127.0.0.1:8000/test/?format=api
- http://127.0.0.1:8000/test.api
- http://127.0.0.1:8000/test/
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from rest_framework.renderers import JSONRenderer from rest_framework.renderers import BrowsableAPIRenderer from .. import models class TestSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class CustomBrowsableAPIRenderer(BrowsableAPIRenderer): def get_default_renderer(self, view): return JSONRenderer() class TestView(APIView): renderer_classes = [CustomBrowsableAPIRenderer, ] def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all().first() ser = TestSerializer(instance=user_list, many=False) return Response(ser.data, template_name='user_detail.html')
注意:若是同時多個存在時,自動根據URL後綴來選擇渲染器。