在以前的django rest framework
其餘組件中,在視圖函數中繼承類都是rest_framework.view.APIView
,這個APIView
是繼承的django
中的View
而且作了封裝和方法重寫的。 那麼在django rest framework
中,還有有沒有提供其餘的類可以繼承?html
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
的內部的一些方法會根據會自動的獲取數據庫查詢結果並分頁和序列化。django
queryset
pagination_class
屬性獲取分頁類進行分頁操做,另外若是這裏沒有重寫,會自動到settings.py
配置文件去找GenericViewSet
實際上使用了多繼承和Mixin
模式,也就是說GenericViewSet
同時繼承了ViewSetMixin, generics.GenericAPIView
兩個父類api
# rest_framework\viewsets.py 源碼 class GenericViewSet(ViewSetMixin, generics.GenericAPIView): pass
在GenericViewSet
中因爲類繼承的前後順序的關係,會先執行ViewSetMixin
類中相關方法。而GenericAPIView
類中的相關方法會被忽略。app
在執行以前要更改一下路由系統iview
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
請求。函數
視圖中基本上和上面同樣,只不過更改了不一樣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)
http://127.0.0.1:8000/api/genericset
,get
方法獲取數據時,返回正常結果post
http://127.0.0.1:8000/api/genericset/
,表示發送post請求添加單條數據,數據添加成功測試
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,
分別對應,建立,獲取單條數據,更新,刪除,或許多條數據。
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中增長正則匹配。
在視圖中,並無增長相應的增刪改查的邏輯卻能完成相應的功能,這是由於繼承的mixin
類中,已經有一一對應的方法,視圖類會自動調用父類的方法。
from rest_framework.viewsets import ModelViewSet class ModelSetView(ModelViewSet): queryset = Role.objects.get_queryset().order_by('id') serializer_class = PagerSerializer pagination_class = PageNumberPagination
獲取第九條數據,返回結果
在ModelSetView
中看到,繼承了多個mixin
類,而這些類又分別封裝了不一樣的對應於增刪給查的方法,所以若是想要自定義一個接口,實現部分http方法,就能夠根據須要繼承不一樣的mixin
類
mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin,