Django Rest framework 之 視圖

在以前的django rest framework其餘組件中,在視圖函數中繼承類都是rest_framework.view.APIView,這個APIView是繼承的django中的View而且作了封裝和方法重寫的。 那麼在django rest framework中,還有有沒有提供其餘的類可以繼承?html

1、GenericAPIView

GenericAPIViewdjango 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

  • get_queryset(): 會獲取數據庫查詢結果,也就是queryset
  • paginate_queryset(roles):會根據重寫的pagination_class屬性獲取分頁類進行分頁操做,另外若是這裏沒有重寫,會自動到settings.py配置文件去找
  • self.get_serializer():就是根據分頁後的對象進行數據的序列化,也會先找到序列化類

2、GenericViewSet

一、源碼分析

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類,因此會進入GenericViewSetas_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)

四、測試

<1>、測試一

http://127.0.0.1:8000/api/genericsetget方法獲取數據時,返回正常結果post

<2>、測試二

http://127.0.0.1:8000/api/genericset/,表示發送post請求添加單條數據,數據添加成功測試

3、ModelSetView

一、源碼分析

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,
相關文章
相關標籤/搜索