drf之模塊

1.介紹

安裝 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)請求走的是APIViewas_view函數服務器

2)APIViewas_view調用父類Viewas_viewDjango原生的),還禁用了csrf認證app

3)在父類的as_view中分發dispatch方法走的又是APIViewdispatch框架

4)完成任務分發,交給視圖類的請求方法處理,獲得請求的響應結果,返回給前臺函數

主要關注APIViewdispatch方法。源碼分析

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

 

2.請求模塊:request對象

源碼入口: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-dataurlencoded,上面三種都能獲取到數據。可是當前臺提交的是json數據時,只有data可以得到,其餘都是空。

 

總結:

drf對原生request作了二次封裝,_request就是原生的request

原生request對象的屬性和方法均可以被drf_request對象直接訪問;

drf請求的全部拼接參數(get請求攜帶的參數)均被解析到query_params中,全部數據包數據(post請求在請求體中的數據)都被解析到data

3.渲染模塊

有兩種渲染方式:jsonbrowser瀏覽器。

渲染模塊源碼入口: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配置中改,具有就在自定義視圖類中加類屬性。

 

4.解析模塊

url拼接參數:只有一種傳參方式:拼接參數到url中(在url中)

數據包參數:有3種:form-dataurlencodedjson

解析模塊源碼入口: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格式提交的數據。

 

5.異常處理模塊

異常模塊源碼入口:APIView類的dispatch方法中的response = self.handle_exception(exc)

自定義異常:

好比get取值取不到時,會出現query does not exist異常,顯示在前臺。

1.settings.pyREST_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:    #默認處理異常時當responseNone直接向前臺展現,自定義就返回接口

    #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)全部通過drfAPIView視圖類產生的異常,均可以經過自定義異常提供異常處理方案(好比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.viewsexception_handler作基礎處理

2)判斷處理的結果(返回值)response,有值表明drf已經處理了,沒值就要本身處理。本身處理,能夠對exc進行異常判斷,而後進行不一樣的處理。爲空二次處理

 

6.響應模塊

1)響應類構造器

def __init__(self, data=None, status=None,
            template_name=None, header=None,
            exception=None, content_type=None):
        pass        

data:響應數據

statushttp響應狀態碼

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={設置的響應頭})

相關文章
相關標籤/搜索