簡(jiǎn)介
APIView 和 Viewset 是 DRF 中引入的視圖類(lèi),Viewset 對(duì) DRF 自身提供的 APIView 進(jìn)行了再次封裝,而 APIView 是對(duì)原生 Django View 的封裝,靈活運(yùn)用 APIView 和 Viewset 可以大幅度提升業(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ù)