DRF-APIView


一、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


免責聲明!

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



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