安裝 pip install djangorestframeworkdjango
註冊:在INSTALLED_APPS列表中寫:」rest_framework」json
drf框架的封裝風格:api
import rest_framework from rest_framework.views import View #視圖 from rest_framework.response import Response #響應 from rest_framework.request import Request #請求 from rest_framework.serializers import Serializer #序列化器 from rest_framework.settings import APISettings #設置 from rest_framework.filters import SearchFilter #過濾器 from rest_framework.pagination import PageNumberPagination #分頁 from rest_framework.authentication import TokenAuthentication #登錄 from rest_framework.permissions import IsAuthenticated #權限 from rest_framework.throttling import SimpleRateThrottle #頻率
drf請求生命週期:瀏覽器
1)請求走的是APIView的as_view函數;服務器
2)在APIView的as_view調用父類View的as_view(Django原生的),還禁用了csrf認證app
3)在父類的as_view中分發dispatch方法走的又是APIView的dispatch框架
4)完成任務分發,交給視圖類的請求方法處理,獲得請求的響應結果,返回給前臺函數
主要關注APIView的dispatch方法。源碼分析
dispatch源碼分析:post
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(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try: #三大認證模塊 self.initial(request, *args, **kwargs) # Get the appropriate handler method 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 #響應模塊 response = handler(request, *args, **kwargs) except Exception as exc: #異常模塊 response = self.handle_exception(exc) #渲染模塊 self.response = self.finalize_response(request, response, *args, **kwargs) return self.response
源碼入口:APIView類的dispatch方法中:request = self.initialize_request(request, *args, **kwargs)
get請求的數據(拼接的參數)能夠經過三個方法獲得:
request._request.GET #二次封裝
request.GET #兼容
request.query_params #用這個 擴展
post請求的數據(數據包)
request._request.POST
request.POST
request.data #經過data拿數據,三種數據方式都能拿
對於form-data和urlencoded,上面三種都能獲取到數據。可是當前臺提交的是json數據時,只有data可以得到,其餘都是空。
總結:
drf對原生request作了二次封裝,_request就是原生的request;
原生request對象的屬性和方法均可以被drf的_request對象直接訪問;
drf請求的全部拼接參數(get請求攜帶的參數)均被解析到query_params中,全部數據包數據(post請求在請求體中的數據)都被解析到data中
有兩種渲染方式:json和browser瀏覽器。
渲染模塊源碼入口:APIView類的dispatch方法中:self.response = self.finalize_response(request, response, *args, **kwargs)
全局配置:
在settings.py配置文件中配置REST_FRAMEWORK,就全局配置全部接口的渲染方式(兩種:方式1:就只是返回json字符串(好比經過postman),方式2:瀏覽器方式的數據:有響應信息和json數據)
局部配置:
在自定義類中定義類屬性(就不去父類中找了)
from rest_framework.renderers import JSONRenderer
render_classes = [JSONRenderer] #必須是列表,由於要迭代
模板渲染配置走的過程:自定義視圖類--->繼承APIView視圖類--->自定義drf配置---->drf默認配置。
全局配置就在自定義drf配置中改,具有就在自定義視圖類中加類屬性。
url拼接參數:只有一種傳參方式:拼接參數到url中(在url中)
數據包參數:有3種:form-data、urlencoded和json。
解析模塊源碼入口:APIView類的dispatch方法中的 request = self.initialize_request(request, *args, **kwargs)
解析配置也有兩種:
全局解析類、局部解析類
全局配置:
在settings.py中的REST_FRAMEWORK字典中,寫入
'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ], #三個都寫上,那麼3個都支持
局部配置:
在自定義類中寫
from rest_framework.parsers import JSONParser parser_classes = [JSONParser] #寫了這個這個類就只支持解析json格式提交的數據。
異常模塊源碼入口:APIView類的dispatch方法中的response = self.handle_exception(exc)
自定義異常:
好比get取值取不到時,會出現query does not exist異常,顯示在前臺。
1.在settings.py的REST_FRAMEWORK字典中全局配置異常模塊 「EXECPTION_HANDLER」 :」api.exception.exception_handler」 讓get_exception_handler從默認的異常處理變爲本身定義的異常處理函數 自定義異常就是提供exception_handler異常處理函數,處理的目的就是讓response必定有值。
2.在應用下api新建一exceptions.py文件 from rest_framework.views import exception_handler as drf_exception_handler form rest_framework.views import Response def exception_handler(exc, context): response = drf_exception_handler(exc, context) #先交給默認的exception_handler處理 if response is None: #默認處理異常時當response爲None直接向前臺展現,自定義就返回接口 #if isinstance(exc, ‘’) 能夠對exc的不一樣類型作判斷,返回不一樣的異常 return Response({ 「detail」: 「服務器錯誤」 }) return response
|
源碼邏輯分析:
首先源碼入口爲APIView類的dispatch方法中的response = self.handle_exception(exc),
handle_exception裏而後執行exception_handler = self.get_exception_handler(),從exception_handler 中獲取response,若是response有值,就返回,沒有值就報錯給前臺。get_exception_handler是從settings中獲取exception_handler函數。exception_handler是處理異常的邏輯,要麼返回response,要麼返回None。能夠在自定義exception_handler函數,而後再配置中指定自定義的異常函數,這樣就會走自定義的。同時爲了複用默認的異常處理,能夠在自定義異常函數中先導入默認的,生成response,再針對response處理(好比是None,返回具體的錯誤)。
總結:
爲何要自定義異常模塊?
1)全部通過drf的APIView視圖類產生的異常,均可以經過自定義異常提供異常處理方案(好比get默認就沒有處理異常,就會在前臺顯示錯誤的細節)。
2)drf默認提供了異常處理方案(在rest_framework.views.exception_handler中),單處理範圍有限
3)drf提供的處理方案有兩種:處理了就返回處理信息,沒處理就返回None(後續就是服務器拋異常給前臺)。
4)自定義異常的目的就是解決drf沒有處理的異常,讓前臺獲得合理的異常信息,後臺記錄異常具體信息。
處理方案:
修改配置文件
REST_FRAMEWORK = {
「EXECPTION_HANDLER」 :」api.exception.exception_handler」
}
自定義exception_handler函數。
1)先將異常處理交給rest_framework.views的exception_handler去作基礎處理
2)判斷處理的結果(返回值)response,有值表明drf已經處理了,沒值就要本身處理。本身處理,能夠對exc進行異常判斷,而後進行不一樣的處理。爲空二次處理。
(1)響應類構造器
def __init__(self, data=None, status=None, template_name=None, header=None, exception=None, content_type=None): pass
data:響應數據
status:http響應狀態碼
content_type:繼承父類,默認是json,不用設置。
其餘不用瞭解。
直接在自定義異常返回的Response中帶上有名實參。
return Response({ 「detail」: 「服務器錯誤」 }, status=500, exception=True)
這個500能夠從定義的變量中導入:from rest_framework import status
status=status.HTTP_500_INTERNAL_SERVER_ERROR
常規實例化響應對象:
return Response(data={數據}, status=XXX, headers={設置的響應頭})