Django Rest framework 之 檢視
轉載於Django Rest framework 之 檢視 - 蔚藍的藍 - 部落格園
Django Rest framework 之 檢視
- RESTful 規範
- django rest framework 之 認證(一)
- django rest framework 之 許可權(二)
- django rest framework 之 節流(三)
- django rest framework 之 版本(四)
- django rest framework 之 解析器(五)
- django rest framework 之 序列化(六)
- django rest framework 之 分頁(七)
- django rest framework 之 檢視(八)
在之前的django rest framework
其他元件中,在檢視函式中繼承類都是rest_framework.view.APIView
,這個APIView
是繼承的django
中的View
並且做了封裝和方法重寫的。 那麼在django rest framework
中,還有有沒有提供其他的類能夠繼承?
一、GenericAPIView
GenericAPIView
在django rest framework
中根據APIView
又做了一層封裝。則繼承關係就變成了GenericAPIView——>APIView——>View
from rest_framework.generics import GenericAPIView class GenericView(GenericAPIView): queryset = Role.objects.get_queryset().order_by('id') serializer_class = PagerSerializer pagination_class = PageNumberPagination def get(self,request,*args,**kwargs): roles = self.get_queryset() pager_roles = self.paginate_queryset(roles) ser = self.get_serializer(instance=pager_roles,many=True) return Response(ser.data)
這裡實現的功能和django rest framework
之 分頁中的功能一樣,先獲取資料,分頁,序列化返回。不同的是,這裡由於封裝的作用,GenericAPIView
的內部的一些方法會根據會自動的獲取資料庫查詢結果並分頁和序列化。
- get_queryset(): 會獲取資料庫查詢結果,也就是
queryset
- paginate_queryset(roles):會根據重寫的
pagination_class
屬性獲取分頁類進行分頁操作,另外如果這裡沒有重寫,會自動到settings.py
配置檔案去找 - self.get_serializer():就是根據分頁後的物件進行資料的序列化,也會先找到序列化類
二、GenericViewSet
1、原始碼分析
GenericViewSet
實際上使用了多繼承和Mixin
模式,也就是說GenericViewSet
同時繼承了ViewSetMixin, generics.GenericAPIView
兩個父類
# rest_framework\viewsets.py 原始碼
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
pass
在GenericViewSet
中由於類繼承的先後順序的關係,會先執行ViewSetMixin
類中相關方法。而GenericAPIView
類中的相關方法會被忽略。
2、路由
在執行之前要更改一下路由系統
from django.conf.urls import url
from .views import *
app_name = 'api'
urlpatterns = [
url(r'^generic/$', GenericView.as_view()),
url(r'^genericset/$', GenericSetView.as_view({'get': 'list', 'post': 'create'})),
]
由於在GenericViewSet
的內部重寫了as_view
方法,且繼承關係又先於GenericAPIView
類,所以會進入GenericViewSet
的as_view
方法。但是在as_view
方法中,對路由系統做了略微的改動,需要對方法,做一一對映關係。即'get': 'list', 'post': 'create',get
(獲取單條資料)請求,會進入子類的list
方法,而create
(建立物件)方法則代表了post
請求。
3、檢視
檢視中基本上和上面一樣,只不過更改了不同http請求方法的對應類方法名
from rest_framework.viewsets import GenericViewSet
class GenericSetView(GenericViewSet):
queryset = Role.objects.get_queryset().order_by('id')
serializer_class = PagerSerializer
pagination_class = PageNumberPagination
def list(self,request,*args,**kwargs):
# 獲取資料
roles = self.get_queryset() # models.Role.objects.all()
# [1, 1000,] [1,10]
pager_roles = self.paginate_queryset(roles)
# 序列化
ser = self.get_serializer(instance=pager_roles,many=True)
return Response(ser.data)
def create(self, request, *args, **kwargs):
ret = {}
try:
title = request.data['title']
Role.objects.create(title=title)
print('success')
except Exception as e:
print(e)
4、測試
<1>、測試一
http://127.0.0.1:8000/api/genericset
,get
方法獲取資料時,返回正常結果
<2>、測試二
http://127.0.0.1:8000/api/genericset/
,表示傳送post請求新增單條資料,資料新增成功
三、ModelSetView
1、原始碼分析
ModelSetView
做的更徹底,他又一次繼承了GenericViewSet
,並且在此之前又繼承了其他幾個類,因此功能更多,變成了ModelViewSet——>GenericViewSet——>APIView——>View
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass
從這些類的名字可以大概看出,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,.ListModelMixin,
分別對應,建立,獲取單條資料,更新,刪除,或許多條資料。
2、路由
from django.conf.urls import url
from django.urls import path
from .views import *
app_name = 'api'
urlpatterns = [
url(r'^modelset/(?P<pk>\d+)/$', ModelSetView.as_view({'get': 'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
]
由於在獲取,刪除,更新資料的時候需要這頂資料的唯一標識,這裡是pk主鍵,因此需要在url中增加正則匹配。
3、檢視
在檢視中,並沒有增加相應的增刪改查的邏輯卻能完成相應的功能,這是因為繼承的mixin
類中,已經有一一對應的方法,檢視類會自動呼叫父類的方法。
from rest_framework.viewsets import ModelViewSet
class ModelSetView(ModelViewSet):
queryset = Role.objects.get_queryset().order_by('id')
serializer_class = PagerSerializer
pagination_class = PageNumberPagination
獲取第九條資料,返回結果
4、自定義
在ModelSetView
中看到,繼承了多個mixin
類,而這些類又分別封裝了不同的對應於增刪給查的方法,因此如果想要自定義一個介面,實現部分http方法,就可以根據需要繼承不同的mixin
類
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,