1. 程式人生 > >Django-rest-framework(三)view and viewsets使用

Django-rest-framework(三)view and viewsets使用

spa stc pytho 直接 內容 framework generics route paginator

DRF 中有多種view和viewsets,我整理了一下,如下圖所示,接下來,我們分別了解下view,viewsets。
技術分享圖片

APIView

所有的view,viewsets都是繼承APIView,而APIView是繼承的django的django.views.generic.View, 然後增加了一些通用的操作,和重載了as_view,dispatch,options,http_method_not_allowed 方法來適應DRF相關的配置和後續的使用。
在直接使用APIView的時候,就和使用django View一樣,分發規則也是一樣,GET請求分發到了get方法,POST請求分發到post方法, 所以路由的註冊方式也一樣。所以在這裏不做演示了。

GenericAPIView

通用view的基礎視圖,其他的基礎view都是繼承了這個view,我們可以來看看源碼裏面實現了那些個方法

# 為了簡化,我刪掉了註釋和具體的實現,
class GenericAPIView(views.APIView):
    queryset = None # 這些會在mixins中用到
    serializer_class = None
    lookup_field = ‘pk‘
    lookup_url_kwarg = None
    pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
    def get_queryset(self):
    def get_object(self):
    def get_serializer(self, *args, **kwargs):
    def get_serializer_class(self):
    def get_serializer_context(self):
    def filter_queryset(self, queryset):
    @property
    def paginator(self):
    def paginate_queryset(self, queryset):
    def get_paginated_response(self, data):

可以看出,在這裏,我們定義了queryset,serializer相關的操作。我們也可以繼承GenericAPIView 來使用定義好的一些方法。

drf-mixins

在這裏,我們插入mixins這一部分,因為後面要介紹的這些view,viewset,都是使用了這種方式實現,在DRF中,有5種mixin,我們還是看看源碼裏面,

# 還是刪除了多余的代碼,只看有哪些方法,
# 一共有5種mixin,分別實現列表顯示,單個資源顯示,增加,修改,刪除操作。
# 後面講解的views,veiwsets就是通過繼承不同的mixin來實現對應功能
# 在這些方法的實現中,需要用到queryset,serializers,所以使用了mixin的時候,需要在view裏指定這兩個參數
class CreateModelMixin(object):
    def create(self, request, *args, **kwargs):

class ListModelMixin(object):
    def list(self, request, *args, **kwargs):
    
class RetrieveModelMixin(object):
    def retrieve(self, request, *args, **kwargs):

class UpdateModelMixin(object):
    def update(self, request, *args, **kwargs):

class DestroyModelMixin(object):
    def destroy(self, request, *args, **kwargs):

*APIView

本部分講解以APIView結尾這這些個views,包括CreateAPIView,ListAPIView,RetrieveAPIView, DestroyAPIView,UpdateAPIView, ListCreateAPIView, RetrieveUpdateAPIView, RetrieveDestroyAPIView, RetrieveUpdateDestroyAPIView。這些都是通過繼承GenericAPIView 和不同的mixin實現,所以我們只選擇其中的一個來作為講解,下面看看ListAPIView 中的內容

class ListAPIView(mixins.ListModelMixin,
                  GenericAPIView):
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

因為繼承的GenericAPIView,並沒有修改分發方式,所以也是GET請求分發到get方法,又因為繼承了ListModelMixin,所以會有list(self)方法,於是自然而然的,就在get方法中,調用self.list()去使用ListModelMixin中定義的方法。其他的views類似,都是把對應的請求轉發到合適的mixin裏面。至此,drf中的views就完了。

viewsets

下面,我們來研究研究viewsets了,它不同與django原生的view,因為有修改分發方式,所以處理上會有些許的不同,還是老規矩,上源碼。

使用

class ViewSetMixin(object):
    #代碼就不貼了,需要配合著看route才能理解,準備後面單獨開一篇來配合著route的處理來寫,
    #在這裏,我們只需要知道在這個類中,重寫了分發規則as_view(),
    #規則大概來說就是,將對應的請求分發到list,create等在mixins定義了的方法中, 比如說,get請求分發到list,或者retrieve。

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    pass
    
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericViewSet):
    # model的只讀接口,實現了列表頁和詳情頁的
    pass
                           
class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
    # model 的增刪改查的接口
    pass

通過源碼,我們可以發現,我們可以自己選擇繼承GenericViewSet 和對應的mixins來實現我們所需要的接口。

路由註冊

因為改了分發方式,所以,不能簡單的像之前的 path(‘view‘, View.as_view())一樣了,我們需要像下面這樣引入route。

from myapp.views import ViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r‘users‘, ViewSet) # url 為 "/api/user/"

urlpatterns = [
    path(‘api/‘, include(router.urls), name=‘api‘),
    ]

Django-rest-framework(三)view and viewsets使用