位置:
from rest_framework.views import APIView
繼承APIView類視圖形式的路由:
path('booksapiview/', views.BooksAPIView.as_view()), #在這個地方應該寫個函式記憶體地址
繼承APIView類的視圖函式:
from rest_framework.views import APIView
class BooksAPIView(APIView):
def get(self):
pass
def post(self):
pass
APIView原始碼分析:
繼承了APIView的視圖函式,最終執行的是APIView里的as_view方法
@classmethod
def as_view(cls, **initkwargs):
"""
Store the original class on the view function.
This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation
# 1.呼叫APIView父類,也就是View類中的as_view方法,將其回傳值view在賦值給view
view = super().as_view(**initkwargs)
# 2.這里踐行了一切皆物件的原則,將cls這個視圖類給了view.cls,下面哪個也是一樣
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
# 3.這句話的意思就是以后所有繼承APIView的試圖函式都沒有csrf認證了,和View類一樣,APIview類的as_view方法最后也回傳了view
# 只不過apiview新增了去除csrf認證這里
return csrf_exempt(view)
注意:上述回傳的view記憶體地址,需要去找dispatch方法是先去apiview里找,而不是view類中的dispatch了
apiview里的dispatch方法分析:
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
# 這里的request是self.initialize_request這個方法回傳的新的由rest_framework中的Request類實體化產生的request物件
request = self.initialize_request(request, *args, **kwargs)
# 又把新的request物件給了視圖函式中的request,從此,視圖函式中的request就是新的request物件了
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
# 這里執行了apiview里的initial方法,這個方法里面包含了三大認證模塊(重要)
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
# 三大認證過了之后,繼續走,這里和view里面差不多,通過反射得到對應請求方式的函式地址
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模塊
response = handler(request, *args, **kwargs)
# 這里是三大認證出例外的例外模塊
except Exception as exc:
response = self.handle_exception(exc)
# 渲染模塊,對response這個相應結果在進行包裝(就是在前端看到的由rest_framework渲染出來的資料結果頁面)
self.response = self.finalize_response(request, response, *args, **kwargs)
# 回傳該渲染模塊
return self.response
def initial(self, request, *args, **kwargs):
# 該方法最重要的就是下面三句代碼
# Ensure that the incoming request is permitted
# 這個是認證組件
self.perform_authentication(request)
# 這個是權限組件
self.check_permissions(request)
# 這個是頻率組件
self.check_throttles(request)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/519044.html
標籤:其他
上一篇:CopyOnWriteArrayList與CopyOnWriteArraySet詳解
下一篇:淺談PHP設計模式的工廠模式
