Django Rest framework 之 視圖


在之前的django rest framework其他組件中,在視圖函數中繼承類都是rest_framework.view.APIView,這個APIView是繼承的django中的View並且做了封裝和方法重寫的。 那么在django rest framework中,還有有沒有提供其他的類能夠繼承?

一、GenericAPIView

GenericAPIViewdjango rest framework中根據APIView又做了一層封裝。則繼承關系就變成了GenericAPIView——>APIView——>View

from rest_framework.generics import GenericAPIView

class GenericView(GenericAPIView):
    queryset = Role.objects.get_queryset().order_by('id')
    serializer_class = PagerSerializer
    pagination_class = PageNumberPagination

    def get(self,request,*args,**kwargs):

        roles = self.get_queryset()
        pager_roles = self.paginate_queryset(roles)
        ser = self.get_serializer(instance=pager_roles,many=True)
        return Response(ser.data)

這里實現的功能和django rest framework 之 分頁中的功能一樣,先獲取數據,分頁,序列化返回。不同的是,這里由於封裝的作用,GenericAPIView的內部的一些方法會根據會自動的獲取數據庫查詢結果並分頁和序列化。

  • get_queryset(): 會獲取數據庫查詢結果,也就是queryset
  • paginate_queryset(roles):會根據重寫的pagination_class屬性獲取分頁類進行分頁操作,另外如果這里沒有重寫,會自動到settings.py配置文件去找
  • self.get_serializer():就是根據分頁后的對象進行數據的序列化,也會先找到序列化類

二、GenericViewSet

1、源碼分析

GenericViewSet實際上使用了多繼承和Mixin模式,也就是說GenericViewSet同時繼承了ViewSetMixin, generics.GenericAPIView兩個父類

# rest_framework\viewsets.py 源碼

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    pass

GenericViewSet中由於類繼承的先后順序的關系,會先執行ViewSetMixin類中相關方法。而GenericAPIView類中的相關方法會被忽略。

2、路由

在執行之前要更改一下路由系統

from django.conf.urls import url

from .views import *
app_name = 'api'

urlpatterns = [
    url(r'^generic/$', GenericView.as_view()),
    url(r'^genericset/$', GenericSetView.as_view({'get': 'list', 'post': 'create'})),
]

由於在GenericViewSet的內部重寫了as_view方法,且繼承關系又先於GenericAPIView類,所以會進入GenericViewSetas_view方法。但是在as_view方法中,對路由系統做了略微的改動,需要對方法,做一一映射關系。即'get': 'list', 'post': 'create',get(獲取單條數據)請求,會進入子類的list方法,而create(創建對象)方法則代表了post請求。

3、視圖

視圖中基本上和上面一樣,只不過更改了不同http請求方法的對應類方法名

from rest_framework.viewsets import GenericViewSet

class GenericSetView(GenericViewSet):
    queryset = Role.objects.get_queryset().order_by('id')
    serializer_class = PagerSerializer
    pagination_class = PageNumberPagination

    def list(self,request,*args,**kwargs):
        # 獲取數據
        roles = self.get_queryset() # models.Role.objects.all()
        # [1, 1000,]     [1,10]
        pager_roles = self.paginate_queryset(roles)
        # 序列化
        ser = self.get_serializer(instance=pager_roles,many=True)
        return Response(ser.data)

    def create(self, request, *args, **kwargs):
        ret = {}
        try:
            title = request.data['title']
            Role.objects.create(title=title)
            print('success')
        except Exception as e:
            print(e)

4、測試

<1>、測試一

http://127.0.0.1:8000/api/genericsetget方法獲取數據時,返回正常結果

<2>、測試二

http://127.0.0.1:8000/api/genericset/,表示發送post請求添加單條數據,數據添加成功

三、ModelSetView

1、源碼分析

ModelSetView做的更徹底,他又一次繼承了GenericViewSet,並且在此之前又繼承了其他幾個類,因此功能更多,變成了ModelViewSet——>GenericViewSet——>APIView——>View

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

從這些類的名字可以大概看出,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,.ListModelMixin,分別對應,創建,獲取單條數據,更新,刪除,或許多條數據。

2、路由

from django.conf.urls import url
from django.urls import path

from .views import *
app_name = 'api'

urlpatterns = [
    url(r'^modelset/(?P<pk>\d+)/$', ModelSetView.as_view({'get': 'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
]

由於在獲取,刪除,更新數據的時候需要這頂數據的唯一標識,這里是pk主鍵,因此需要在url中增加正則匹配。

3、視圖

在視圖中,並沒有增加相應的增刪改查的邏輯卻能完成相應的功能,這是因為繼承的mixin類中,已經有一一對應的方法,視圖類會自動調用父類的方法。

from rest_framework.viewsets import ModelViewSet

class ModelSetView(ModelViewSet):
    queryset = Role.objects.get_queryset().order_by('id')
    serializer_class = PagerSerializer
    pagination_class = PageNumberPagination

獲取第九條數據,返回結果

4、自定義

ModelSetView中看到,繼承了多個mixin類,而這些類又分別封裝了不同的對應於增刪給查的方法,因此如果想要自定義一個接口,實現部分http方法,就可以根據需要繼承不同的mixin

mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM