DRF(Django RestFramework)視圖集總結

視圖集

視圖集有四個封裝類,ViewSet基礎封裝、GenericViewSet進一步封裝查詢集和序列化器、ModelViewSet進一步封裝action、ReadOnlyModelViewSet提取只讀action。以下是展開介紹。

一、ViewSet

# 源碼
class ViewSet(ViewSetMixin, views.APIView):
    pass

沒錯,源碼中ViewSet就是隻有繼承而沒有實現任何方法&定義任何屬性,我們對APIView已經不陌生了,我上一篇DRF類視圖中有,它主要實現請求,響應,驗證,異常,限流等。主要看ViewSetMixin類。

class ViewSetMixin(object):
    """
    Overrides `.as_view()` so that it takes an `actions` keyword that performs
    the binding of HTTP methods to actions on the Resource.
    For example
    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    重寫了as_view方法,它需要執行一個`actions`關鍵字
     HTTP方法綁定到資源上的操作
    """
    def as_view(cls, actions=None, **initkwargs)
        # 有興趣可以具體看實現,這裏就不復制了
        pass 

由源碼可以看出,僅僅提供了as_view方法將請求方法綁定到了actions關鍵字上,並沒有給出actions的具體實現,所以我們在使用ViewSet的時候,需要自己定義出action方法(查詢集和序列化器需要手動實例化調用、異常拋出等),然後通過as_view綁定請求方法即可。

# 舉例1.1
# 繼承視圖集ViewSet
class BooksAPIViewSet(ViewSet):
    # 定義action中的list實現查詢所有
    def list(self, request):
        # 手動實現查詢集
        books = BookInfo.books.all()
        # 手動使用序列化器
        serializer = BookInfoModelSerializer(books, many=True)
        # 返回響應,APIView中實現的Response響應對象
        return Response(serializer.data)

    # 定義action中的retrieve檢索條件
    def retrieve(self, request, pk):
        try:
            book = BookInfo.books.get(id=pk)
        except BookInfo.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        serializer = BookInfoSerializer(book)
        return Response(serializer.data)

我們實現了視圖集,爲了使他生效,我們還需要指定他們的url。

# as_view中實現了get->list的綁定,是我們發送的get /books/請求能夠生效
url(r'^books/$', views.BooksAPIViewSet.as_view({'get': 'list'})),
# 綁定get->retrieve,使得get /books/id/生效
url(r'^books/(?P<pk>\d+)/$', views.BooksAPIViewSet.as_view({'get': 'retrieve'})),

綜上:繼承ViewSet,需要自定義action,action中需要自己實現查詢集和序列化器,url中as_view需要綁定方法和action的對應關係

二、GenericViewSet

# 源碼
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    pass

同樣GenericViewSet類中也沒有任何實現,全部繼承自ViewSetMixin和GenericAPIView。DRF類視圖中有GenericAPIView的介紹,它主要實現指定查詢集queryset/get_queryset/get_object和指定序列化器serializer_class/get_serializer_class等。ViewSetMixin類剛剛提過主要重寫實現了as_view()用於request方法和action的綁定。注意:GenericViewSet一般需要和5種擴展類執行。

# 舉例1.2
# 繼承視圖集GenericViewSet
class BooksAPIViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    # 指定查詢集和序列化器
    # 之所以不用定義get/post方法,是因爲重寫了as_view方法,將get映射爲了list方法
    # 之所以不用第一action,是因爲繼承了ListModelMixin等擴展類
    queryset = BookInfo.books.all()
    serializer_class = BookInfoModelSerializer

三、ModelViewSet

# 源碼
class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
     pass

同樣,我們的ModelViewSet中也沒有任何功能的具體實現,單純的繼承五個擴展類的功能和GenericViewSet的功能。很明顯,五個擴展類主要實現了Create(增)List/Retrieve(查)Update(改)Destroy(刪)。GenericViewSet主要實現了序列化器的指定,查詢集的指定,和as_view的重寫。

四、ReadOnlyModelViewSet

# 源碼
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericViewSet):
    pass

由此可以看出ReadOnlyModelViewSet僅僅是查詢集。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章