【DRF】快速上手 View APIView Viewset

簡(jiǎn)介

APIViewViewset 是 DRF 中引入的視圖類(lèi),Viewset 對(duì) DRF 自身提供的 APIView 進(jìn)行了再次封裝,而 APIView 是對(duì)原生 Django View 的封裝,靈活運(yùn)用 APIViewViewset 可以大幅度提升業(yè)務(wù)開(kāi)發(fā)效率,且大大提升了代碼的可維護(hù)性。


三者區(qū)別

繼承關(guān)系

    ViewSet(GenericViewSet)        -drf
        APIView(GenericAPIView)    -drf
            View                   -django

【View】

來(lái)自 Django 原生中,是所有基于類(lèi)的view的父類(lèi),它負(fù)責(zé)將視圖連接到URL、HTTP 方法調(diào)度(GET,POST等)和其它簡(jiǎn)單的功能。

【APIView】

APIView 是 DRF 中所有view的父類(lèi),本身繼承于Django的view,只有簡(jiǎn)單的調(diào)度方法和檢查。

【ViewSet】

ViewSet 繼承了APIView 之外,還加入了 .as_view().initialize_request(),并可以結(jié)合 router 映射路由

三者的不同

三者之間最重要的不同在于 mixin

APIView 和 View

在APIView中仍以常規(guī)的類(lèi)視圖定義方法來(lái)實(shí)現(xiàn)get()post() 或者其他請(qǐng)求方式的方法

新增的自定義屬性

  • authentication_classes 列表或元祖,身份認(rèn)證類(lèi)
  • permissoin_classes 列表或元祖,權(quán)限檢查類(lèi)
  • throttle_classes 列表或元祖,流量控制類(lèi)
請(qǐng)求和返回使用的 DRF 的Request Response而不是django的HttpRequest HttpResponse
請(qǐng)求傳入時(shí)進(jìn)行身份驗(yàn)證,并在傳給處理方法前進(jìn)行權(quán)限檢驗(yàn)
任何APIException都會(huì)被捕捉并放入合適的想要中
response返回的內(nèi)容需是序列化的json

GenericAPIView 和 APIView

GenericAPIView 繼承于 APIView

GenericAPIView新加的配置項(xiàng)

  • 【列表視圖】與【詳情視圖】通用

    • queryset 指定作用的 model 數(shù)據(jù)范圍【如果設(shè)置了 get_queryset() 這個(gè)配置則不生效】
    • serializer_class 設(shè)置視圖使用的 serializer
  • 【列表視圖】使用

    • pagination_class 設(shè)置分頁(yè)
    • filter_backends 設(shè)置過(guò)濾
  • 【詳情頁(yè)視圖】使用

    • lookup_field 查詢單一數(shù)據(jù)庫(kù)對(duì)象時(shí)使用的條件字段,默認(rèn)為'pk'
    • lookup_url_kwarg 查詢單一數(shù)據(jù)時(shí)URL中的參數(shù)關(guān)鍵字名稱,默認(rèn)與look_field相同

GenericAPIView新加的方法

  • get_queryset()
    【列表視圖與詳情視圖通用】
    返回視圖使用的查詢集,是列表視圖與詳情視圖獲取數(shù)據(jù)的基礎(chǔ),默認(rèn)返回queryset屬性,可以重寫(xiě),例如:
def get_queryset(self):
    user = self.request.user
    return user.accounts.all()
  • get_serializer_class()
    【列表視圖與詳情視圖通用】
    返回序列化器類(lèi),默認(rèn)返回serializer_class,可以重寫(xiě),例如:
def get_serializer_class(self):
    if self.request.user.is_staff:
        return FullAccountSerializer
    return BasicAccountSerializer
  • get_serializer(self, args, *kwargs)
    【列表視圖與詳情視圖通用】
    返回序列化器對(duì)象,被其他視圖或擴(kuò)展類(lèi)使用,如果我們?cè)谝晥D中想要獲取序列化器對(duì)象,可以直接調(diào)用此方法。
    注意,在提供序列化器對(duì)象的時(shí)候,REST framework會(huì)向?qū)ο蟮腸ontext屬性補(bǔ)充三個(gè)數(shù)據(jù):request、format、view,這三個(gè)數(shù)據(jù)對(duì)象可以在定義序列化器時(shí)使用。

  • get_object()
    【詳情視圖使用】
    返回詳情視圖所需的模型類(lèi)數(shù)據(jù)對(duì)象,默認(rèn)使用lookup_field參數(shù)來(lái)過(guò)濾queryset。
    在試圖中可以調(diào)用該方法獲取詳情信息的模型類(lèi)對(duì)象。
    若詳情訪問(wèn)的模型類(lèi)對(duì)象不存在,會(huì)返回404。
    該方法會(huì)默認(rèn)使用APIView提供的check_object_permissions方法檢查當(dāng)前對(duì)象是否有權(quán)限被訪問(wèn)。

# url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
class BookDetailView(GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
 
    def get(self, request, pk):
        book = self.get_object()
        serializer = self.get_serializer(book)
        return Response(serializer.data)
  • get_serializer_context()
  • filter_queryset()
   GenericAPIView 可組合的 mixin
       mixins.CreateModelMixin
       mixins.ListModelMixin
       mixins.RetrieveModelMixin
       mixins.UpdateModelMixin
       mixins.DestroyModelMixin
   
   GenericAPIView 已經(jīng)組合的 mixin (與GenericAPIView放在同一目錄)
       CreateAPIView = GenericAPIView + mixins.CreateModelMixin (POST 有 create 方法)
       ListAPIView = GenericAPIView + mixins.ListModelMixin (GET 有 list 方法)
       RetrieveAPIView = GenericAPIView + mixins.RetrieveModelMixin (GET 有 retrieve 方法)
       DestroyAPIView = GenericAPIView + mixins.DestroyModelMixin
       UpdateAPIView = GenericAPIView + mixins.UpdateModelMixin
       ListCreateAPIView = GenericAPIView + mixins.ListModelMixin + mixins.CreateModelMixin
       RetrieveUpdateAPIView = GenericAPIView + mixins.RetrieveModelMixin + mixins.UpdateModelMixin
       RetrieveDestroyAPIView = GenericAPIView + mixins.RetrieveModelMixin + mixins.DestroyModelMixin
       RetrieveUpdateDestroyAPIView = GenericAPIView + mixins.RetrieveModelMixin + mixins.DestroyModelMixin + mixins.DestroyModelMixin

ViewSet 和 APIView

ViewSet 和 APIView 的區(qū)別:

ViewSet 繼承于 APIView 的同時(shí),多了一個(gè) ViewSetMixin
ViewSetMixin 多了一個(gè) .as_view() 方法,可將 get、post 等綁定到指定方法上
ViewSet 需要借助 router 實(shí)現(xiàn)配置 url
ViewSetMixin 還多了一個(gè) .initialize_request()
initialize_request 給 request 綁定了很多的 action,主要用于動(dòng)態(tài)的 serializers

GenericViewSet 和 ViewSet

ViewSet 繼承于 APIView
GenericViewSet 繼承于 GenericAPIView

GenericViewSet 已經(jīng)組合的 mixin (與 GenericViewSet 放在同一目錄)

    ReadOnlyModelViewSet = GenericViewSet + mixins.RetrieveModelMixin + mixins.ListModelMixin
    ModelViewSet = GenericViewSet + mixins.CreateModelMixin + mixins.RetrieveModelMixin + UpdateModelMixin + mixins.DestroyModelMixin + mixins.ListModelMixin

引入Viewset

from rest_framework import viewsets

Viewsets包含的Class(常用的)

0.ViewSetMixin

簡(jiǎn)介:Viewset的基類(lèi),它重寫(xiě)了原來(lái) django view 中 .as_view() 方法,使得注冊(cè)Url變得更加簡(jiǎn)單,原生 Django View 通過(guò)重寫(xiě) get 和 post 方法的具體視圖來(lái)達(dá)到實(shí)現(xiàn)邏輯
在 Viewset 中則可通過(guò):

view = MyViewSet.as_view({'get': 'list', 'post': 'create'})

指定請(qǐng)求調(diào)用的函數(shù)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容