1. 程式人生 > 其它 >drf的基本使用、APIView原始碼分析和CBV原始碼拓展

drf的基本使用、APIView原始碼分析和CBV原始碼拓展

目錄

cbv原始碼拓展

擴充套件,如果我在Book檢視類中重寫dispatch方法
	-可以實現,在get,post方法執行之前或者之後執行程式碼,完成類似裝飾器的效果
       def dispatch(self, request, *args, **kwargs):
            # 請求執行前程式碼
            response=super().dispatch(request, *args, **kwargs)
            # 請求執行後代碼
            return response
        
        # 這樣你的get、post...請求來的時候和結束後就會執行自定義的程式碼

DRF基本使用及執行流程分析(3星)

基本使用

在views.py中

from rest_framework.views import APIView  # 繼承這個類
from rest_framework.response import Response  # 這個是drf封裝的


class BookAPIView(APIView):
    def get(self, request, *args, **kwargs):
        return Response('get請求')

    def post(self, request, *args, **kwargs):
        return Response('post請求')

在urls.py中

from app01 import views

urlpatterns = [
    path('book/', views.BookAPIView.as_view())
]

APIView執行流程(原始碼分析)

0. APIView繼承了django的View

1. APIView中重寫了as_view
    @classmethod
    def as_view(cls, **initkwargs):
        # 呼叫父類的as_view
        view = super().as_view(**initkwargs)
        # 只要繼承APIView以後所有的檢視都沒有csrf保護了,不管是否註釋掉中介軟體 
        return csrf_exempt(view)
    
2 再執行self.dispatch()---->APIView的dispatch
    def dispatch(self, request, *args, **kwargs):
		# 包裝了一個新的request物件,基於原來的request物件包裝你的
        # 這個request物件是新的request物件,是drf提供的Request類的物件
        # 新的request包含,原來老的request(django的request)
        # self._request = request(老)
        request = self.initialize_request(request, *args, **kwargs)
        #print(request._request)  老的request物件
        try:
        	# 認證,許可權,頻率。。。
            self.initial(request, *args, **kwargs)
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            #檢視類中get或其他請求方法的執行
            response = handler(request, *args, **kwargs)
        except Exception as exc:
            # 如果在檢視類中有錯誤,會被捕獲(全域性異常處理)
            response = self.handle_exception(exc)
        #把response包裝了一下,返回了
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
3 在檢視類中使用的request物件是新的request物件,老的是request._request
	-新的request.GET拿到的還是老的GET,原理如下(Request類重寫了__getattr__)
       def __getattr__(self, attr):
            try:
                return getattr(self._request, attr)
            except AttributeError:
                return self.__getattribute__(attr)
            
4 結論:以後繼承了APIView後,request物件成了新的,但是跟原來一樣用

5 新的request物件中有一個屬性  data
	-data是post請求攜帶的資料----》字典
    -無論是什麼編碼格式,只要是post提交的資料,都在request.data中
	-以後再取值,都從request.data中取

總結

以後如果使用了drf, 繼承了APIView(drf提供了很多view, 他們都是繼承了APIView), 執行流程如下:

1.包裝了一個新的request,在檢視函式中使用時,跟原來沒有區別

2.POST請求在request.data中取

3.GET請求在request.query_params中取

Request類(drf的)中需要掌握的

  1. request.data 方法包裝成了資料屬性
  2. request.query_params 就是request._request.GET
  3. request.FIELS 還是取上傳的檔案

APIView類

  1. 包裝了新的request
  2. 執行了認證,許可權,頻率...
  3. 處理了全域性異常
  4. 包裝了response物件