一、APIView請求生命周期
1、APIView類繼承View類,重寫了as_view和dispatch方法;
2、重寫的as_view方法,主題還是View的as_view,只是在返回視圖view函數地址時,局部禁用csrf認證
3、重寫的dispatch方法:
在執行請求邏輯前:請求模塊(二次封裝request)、解析模塊(三種數據包格式的數據解析);
在執行請求邏輯中:異常模塊(執行出現任何異常交個異常模塊處理)
在執行請求邏輯后:響應模塊(二次封裝response)、渲染模塊(響應的數據能JSON和頁面兩種渲染);
二、請求模塊
1、將wsgi的request對象轉化成drf的Request類對象;
2、封裝后的request對象完全兼容wsgi的request對象,並且將原request保存在新的request._request;
3、重寫格式化請求數據存放位置:
拼接參數:request.query_params
數據包參數:request.data
#源碼解析:
#入口:APIview的dispatch方法的request=self.initialize_request(request,*args,**kwargs)
#print(request._request.method)#在內部將wsgi的request賦值給request._request
#print(request.method)#就是通過__getattr__走的是request._request.method
#print(request.query_params) #走的是方法屬性,就是給request._request.GET重新命名
#print(request.data)#走的是方法屬性,值依賴於request._full_data
三、解析模塊
1、全局配置所有視圖類的解析方式,解析配置可以配置三種;
2、局部配置當前視圖類的解析方式,解析配置可以配置三種;
3、配置低的查找順序:局部(視圖類的類屬性)=>全局(setting文件的drf配置)=>默認(drf的默認配置);
注:全局局部配置是重點。
局部:
全局:
#源碼解析:
#入口:APIView的dispatch方法的request=self.instialize_request(request,*args,**kwargs)
#獲取解析類:parsers = self.get_parsers(),
#進行局部-全局-默認配置查找順序進行查找:
return [parser() for parser in self.parser_classes]
#局部配置(在視圖類中配置):
parser_classes = [JSONParser, FormParser, MultiPartParser]
#全局配置(在setting中配置):
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
],
四、響應模塊
'data':響應數據(熟悉)
'status':響應的網絡狀態碼(熟悉)
template_name:drf完成前后台不分離返回頁面,但是就不可以返回data(不需要掌握)
headers:響應頭,一般不規定,走默認
exception:一般異常響應,會將其設置成True,默認False(不設置也沒事)
content_type:默認就是application/json不需要處理
五、渲染模塊(了解)
Postman軟件測試請求結果是json,瀏覽器請求結果是頁面
局部:
全局:
#局部配置渲染類(在視圖類中配置):只適用當前視圖類
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
#全局配置渲染類:適用於所有視圖類
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
# 'rest_framework.renderers.BrowsableAPIRenderer', # 上線后盡量關閉
],
六、異常模塊
1、所有經過drf的AIPView視圖類產生的異常,都可以提供異常處理方案(包括三大認證);
2、drf默認提供了異常處理方案(rest_framework.views.exception_handler),但是
處理范圍有限;
3、drf提供的處理方案兩種,處理后的異常(一般都是前端出現的錯誤)返回異常現象,沒有處理(一般都是服務器錯誤)返回None;
4、自定義異常的目的就是解決drf沒有處理的異常,讓前台得到合理的異常信息返回,后台記錄異常的具體信息;
ps:ORM查詢時的錯誤drf一般不自動處理.
'''
#異常模塊:APIView類的dispatch方法中
request=self.handle_exception(exc)#點進去
#獲取處理異常的句柄(方法)
#一層層看源碼,走的是配置文件,拿到的是rest_framework.views的exception_handler
#自定義:直接寫exceptiot_handler函數,在自己的配置文件配置EXCEPTION_HANDLER指向自己寫的
exception_handler = self.get_exception_handler()
#異常處理的結果
#自定義異常就是提供exception_handler異常處理函數,處理的目的就是讓response一定有值
response= exception_handler(exc,context)
'''
# 一定要在settings文件中將異常模塊配置自己的異常處理函數
#settings中配置:
REST_FRAMEWORK = {
# 全局配置異常模塊
'EXCEPTION_HANDLER': 'api.exception.exception_handler', # api為應用名
}
#自定義異常處理py文件
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
# 先交個drf處理客戶端異常,如果結果response為None代表服務器異常,自己處理
# 最終一定要在日志文件中記錄異常現象
def exception_handler(exc, context):
response = drf_exception_handler(exc, context)
detail = '%s - %s - %s' % (context.get('view'), context.get('request').method, exc)
if not response: # 服務端錯誤
response = Response({'detail': detail})
else:
response.data = {'detail': detail}
# 核心:要將response.data.get('detail')信息記錄到日志文件
# logger.waring(response.data.get('detail'))
return response