一、分頁
當訪問的數據量特別大的時候,我們需要對數據進行分頁顯示,可以通過如下三種方式進行,分別介紹如下:
1、根據頁碼分頁
url代碼:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^pagertest/',views.PagerView.as_view()), ]
視圖代碼:

from django.shortcuts import render from rest_framework.views import APIView from .models import UserInfo from rest_framework.response import Response from rest_framework import serializers from rest_framework.pagination import PageNumberPagination class MyPagination(PageNumberPagination): page_size = 2 #默認每頁顯示數據條數 page_query_param = "page" #第幾頁參數,在url中設置 page_size_query_param = "page_size" #定制每頁顯示的數據條數的參數,在url中設置 class PagerSerialize(serializers.ModelSerializer): '''數據序列化類''' class Meta: model = UserInfo fields = "__all__" depth = 2 #用於顯示關聯字段的對應的表的詳細內容 class PagerView(APIView): def get(self,request,*args,**kwargs): user_list=UserInfo.objects.all() #根據url參數,獲取分頁數據 obj=MyPagination() page_user_list=obj.paginate_queryset(user_list,request,self) #數據進行序列化 ser=PagerSerialize(instance=page_user_list,many=True) response=obj.get_paginated_response(ser.data) #返回帶上下頁連接的數據 return response # return Response(ser.data)
2、根據位置和個數分頁(limit offset)
視圖代碼:

from rest_framework.views import APIView from .models import UserInfo from rest_framework.response import Response from rest_framework import serializers from rest_framework.pagination import LimitOffsetPagination class MyPagination(LimitOffsetPagination): # 默認每頁顯示的數據條數 default_limit = 2 # URL中傳入的顯示數據條數的參數 limit_query_param = 'limit' # URL中傳入的數據位置的參數 offset_query_param = 'offset' # 最大每頁顯得條數,默認為None max_limit = None class PagerSerialize(serializers.ModelSerializer): '''數據序列化''' class Meta: model = UserInfo fields = "__all__" depth = 2 #用於顯示關聯字段的對應的表的詳細內容 class PagerView(APIView): def get(self,request,*args,**kwargs): user_list=UserInfo.objects.all() #根據url參數,獲取分頁數據 obj=MyPagination() page_user_list=obj.paginate_queryset(user_list,request,self) #數據進行序列化 ser=PagerSerialize(instance=page_user_list,many=True) response=obj.get_paginated_response(ser.data) #返回帶上下頁連接的數據 return response # return Response(ser.data) #不含上下頁鏈接
3、游標分頁
視圖代碼:

from rest_framework.views import APIView from .models import UserInfo from rest_framework.response import Response from rest_framework import serializers from rest_framework.pagination import CursorPagination class MyPagination(CursorPagination): # URL傳入的游標參數 cursor_query_param = 'cursor' # 默認每頁顯示的數據條數 page_size = 2 # URL傳入的每頁顯示條數的參數 page_size_query_param = 'page_size' # 每頁顯示數據最大條數 max_page_size = 1000 # 根據ID從大到小排列 ordering = "id" class PagerSerialize(serializers.ModelSerializer): '''數據序列化''' class Meta: model = UserInfo fields = "__all__" depth = 2 #用於顯示關聯字段的對應的表的詳細內容 class PagerView(APIView): def get(self,request,*args,**kwargs): user_list=UserInfo.objects.all().order_by('-id') #將數據按照id從大到小排序 #根據url參數,獲取分頁數據 obj=MyPagination() page_user_list=obj.paginate_queryset(user_list,request,self) #數據進行序列化 ser=PagerSerialize(instance=page_user_list,many=True) response=obj.get_paginated_response(ser.data) #返回帶上下頁連接的數據 return response # return Response(ser.data) #不含上下頁鏈接
總結:前兩個者分頁的本質是通過頁碼參數和每頁顯示數據條數等參數,對數據庫中的所有數據進行重頭遍歷,然后展示符合參數要求對應的數據。當數據量很大的時候,這種分頁方式對數據庫查詢的效率影響是很大的。但第三種游標方式分頁的本質是通過記住當前頁面數據的最大、最小id,翻頁時根據記錄的最大或者最小id,查詢下一頁對應的數據,這樣就不會出現每一次翻頁都會重頭遍歷數據的情況,大大的提高了查詢效率。缺點是無法直接跳轉到某一頁。
二、路由
路由系統主要包含如下三種方式,介紹如下。
1、自定義路由
自定義路由主要有如下2種方式,均指向同一個視圖,但是不同的路由用的場景或者說得到的結果是不同的,如下:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 如下:http://127.0.0.1:8002/route/ GET: 查詢(列表);POST: 增加 url(r'^route/$',views.RouteView.as_view()), url(r'^route\.(?P<format>\w+)$',views.RouteView.as_view()), # 必須為format,實例:http://127.0.0.1:8000/route.json
#如下:http://127.0.0.1:8002/route/1/ PUT: 更新;DELETE:刪除;GET: 查詢(單條數據) url(r'^route/(?P<pk>\d+)/$',views.RouteView.as_view()), url(r'^route/(?P<pk>\d+)\.(?P<format>\w+)$',views.RouteView.as_view()), #實例:http://127.0.0.1:8000/route/1.json ]
視圖代碼:
from rest_framework.views import APIView from .models import UserInfo from rest_framework.response import Response from rest_framework import serializers class RouteSerialize(serializers.ModelSerializer): class Meta: model = UserInfo fields = "__all__" depth = 2 #用於顯示關聯字段的對應的表的詳細內容 class RouteView(APIView): def get(self, request, *args, **kwargs): pk=kwargs.get("pk") if pk: obj=UserInfo.objects.filter(pk=pk).first() ser=RouteSerialize(instance=obj,many=False) else: user_list=UserInfo.objects.all() ser=RouteSerialize(instance=user_list,many=True) return Response(ser.data)
2、半自動路由
url代碼:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^route/$', views.RouteView.as_view({'get':'list','post':'create'})),
url(r'^route/(?P<pk>\d+)$', views.RouteView.as_view({'get':'retrieve','put':'update','delete':'destroy',})), ]
如上實例,需要在as_view中設置請求類型及對應的處理方法。
view代碼:
from .models import UserInfo from rest_framework import serializers from rest_framework.viewsets import GenericViewSet,ModelViewSet class RouteSerializer(serializers.ModelSerializer): class Meta: model = UserInfo fields = "__all__" class RouteView(ModelViewSet): #繼承ModelViewSet queryset = UserInfo.objects.all() serializer_class = RouteSerializer
與手動url中的視圖不同的是,此處不再繼承APIView,而是ModelViewSet,因為其深度繼承的關系,內部已經幫我們處理好了相關數據結果,因此並不需要我們做相應的判斷並根據判斷結果查詢數據和返回數據。但是這種情況是的自定制變差。
3、全自動路由
url代碼:
from django.conf.urls import url,include from django.contrib import admin from app01 import views from rest_framework.routers import DefaultRouter route = DefaultRouter() route.register('xxxxx',views.RouteView) ''' 本質如下四種: url(r'^xxxxx/', views.RouteView.as_view({'get':'list','post':'create'})), url(r'^xxxxx\.(?P<format>\w+)', views.RouteView.as_view({'get':'list','post':'create'})), url(r'^xxxxx/(?P<pk>\d+)', views.RouteView.as_view({'get':'retrieve','delete':'destroy','put':'update'})), url(r'^xxxxx/(?P<pk>\d+)\.(?P<format>\w+)', views.RouteView.as_view({'get':'retrieve','delete':'destroy','put':'update'})), ''' urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include(route.urls)), ]
view視圖代碼如半自動路由的相同。總結:推薦使用手動路由,方便自定制操作。
三、視圖
寫視圖函數可繼承的幾個類,如要有如下三種,我們以前經常用到的是APIView,可定制性強。現在我們來了解一下其他的類。
from rest_framework.views import APIView from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import ModelViewSet
四、渲染