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

DRF 中有多種view和viewsets,我整理了一下,以下圖所示,接下來,咱們分別瞭解下view,viewsets。
python

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方法, 因此路由的註冊方式也同樣。因此在這裏不作演示了。django

GenericAPIView

通用view的基礎視圖,其餘的基礎view都是繼承了這個view,咱們能夠來看看源碼裏面實現了那些個方法api

# 爲了簡化,我刪掉了註釋和具體的實現,
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 來使用定義好的一些方法。app

drf-mixins

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

# 仍是刪除了多餘的代碼,只看有哪些方法,
# 一共有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 中的內容post

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就完了。url

viewsets

下面,咱們來研究研究viewsets了,它不一樣與django原生的view,由於有修改分發方式,因此處理上會有些許的不一樣,仍是老規矩,上源碼。spa

使用

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來實現咱們所須要的接口。rest

路由註冊

由於改了分發方式,因此,不能簡單的像以前的 path('view', View.as_view())同樣了,咱們須要像下面這樣引入route。code

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