drf的基本使用、APIView原始碼分析和CBV原始碼拓展
阿新 • • 發佈:2022-03-30
目錄
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的)中需要掌握的
- request.data 方法包裝成了資料屬性
- request.query_params 就是request._request.GET
- request.FIELS 還是取上傳的檔案
APIView類
- 包裝了新的request
- 執行了認證,許可權,頻率...
- 處理了全域性異常
- 包裝了response物件