DRF 框架,全稱為 Django Rest Framework,是 Django 內(nèi)置模塊的擴展,用于創(chuàng)建標準化 RESTful API;它利用 ORM 映射數(shù)據(jù)庫,并自定義序列化數(shù)據(jù)進行返回,多用于前后端分離項目
項目地址:
https://github.com/encode/django-rest-framework
請求模塊:request對象
源碼入口
APIView
類中dispatch
方法中的:request=self.iniialize_request(*args, **kwargs)
,源碼如下:
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
源碼分析
源碼很簡單,第1句parser_context = self.get_parser_context(request)
,我們進入方法get_parser_context
查看源碼:
"""
Returns a dict that is passed through to Parser.parse(),
as the `parser_context` keyword argument.
"""
# Note: Additionally `request` and `encoding` will also be added
# to the context by the Request object.
return {
'view': self,
'args': getattr(self, 'args', ()),
'kwargs': getattr(self, 'kwargs', {})
}
上面的代碼的意思是:返回一個解析的字典以便于Parser.parse()
去解析,另外還通過Request
對象添加了上下文request
和encoding
第二句返回了一個Request
對象,點擊進入查看
![](/d/20211017/ea596a9b47d1f4be56c401672f82de9c.gif)
我們可以分析出,內(nèi)部對request
做了二次封裝,_request
是一個HttpRequest
對象,并且Request
類中還有__getattr__
此方法,代碼如下:
def __getattr__(self, attr):
"""
If an attribute does not exist on this instance, then we also attempt
to proxy it to the underlying HttpRequest object.
"""
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
意思是如果這個實例上不存在一個屬性,那么我們也會嘗試將其代理到底層HttpRequest
對象。接下來我們可以通過案例演示
案例演示
![](/d/20211017/f5bb19617e0351f8963d17ad721394af.gif)
我們創(chuàng)建了TestView
視圖,視圖函數(shù)中打印了3個request
屬性,并且在response
上打了一個斷點,接下來通過url
訪問視圖,進入斷點如下,
![](/d/20211017/634a3fbdc5977aebecc62b44048a8875.gif)
我們可以清楚的看到:
- request是
drf
的Request
對象
- request下有
data
屬性,query_params
屬性,但是沒有GET
屬性
上面還有一個Protected Attributes
屬性,里面包含了_request
屬性
![](/d/20211017/cbc2ff2b8aed6109883e28a4c3c55a51.gif)
我們可以看到_request
是WSGIHttpRequest
對象,所以它會有GET
屬性,所以我們視圖中打印的request.GET
實際上和request._request.GET
是一樣的,因為request
沒有GET
屬性,所以它就會訪問_request
中的GET
屬性,最后我們查看打印結(jié)果,如下:
QueryDict: {'a': ['1']}>
QueryDict: {'a': ['1']}>
QueryDict: {'a': ['1']}>
同樣的,POST
請求也是如此,我們在視圖中添加POST
的請求方式,如下:
def post(self, request, *args, **kwargs):
print(request.POST) # 兼容
print(request._request.POST) # 二次封裝
print(request.data) # 拓展,兼容性最強,3種請求方式都可以
return Response("drf post ok")
我們都知道提交數(shù)據(jù)一般有3種方式
- multipart/form-data
- application/x-www-form-urlencoded
- application/json
首先我們使用multipart/form-data
提交請求數(shù)據(jù),并請求API
![](/d/20211017/85a79fa76e8dee715852b4b6cb0b8077.gif)
我們查看pycharm
打印結(jié)果
QueryDict: {'a': ['1']}>
QueryDict: {'a': ['1']}>
QueryDict: {'a': ['1']}>
可以看到multipart/form-data
這種請求方式,都能打印出來
接著我們使用application/x-www-form-urlencoded
提交請求數(shù)據(jù),并請求API
![](/d/20211017/1e9746a7a4b917ea3cb11f833d681c13.gif)
QueryDict: {'a': ['1']}>
QueryDict: {'a': ['1']}>
QueryDict: {'a': ['1']}>
可以看到application/x-www-form-urlencoded
這種請求方式,都能打印出來
最后我們使用application/json
提交請求數(shù)據(jù),并請求API
![](/d/20211017/7fb23f4a4c3828482d29acc9cf435744.gif)
可以看到application/json
這種請求方式,只有request.data
能打印出來
QueryDict: {}>
QueryDict: {}>
{'a': 1}
所以request.data
兼容性最強
總結(jié)drf
對request
進行了二次封裝,request._request
就是原生的WSGIRequest
原生request
的屬性和方法都可以被drf
的request
對象直接訪問(兼容)drf
請求的所有url
拼接參數(shù)均被解析到query_params
中,所有的數(shù)據(jù)包均被解析到data
中其中post
請求,request.data
的兼容性最強,能兼容前臺傳輸?shù)?code>json格式的數(shù)據(jù)
到此這篇關(guān)于Django(48)drf請求模塊源碼分析 的文章就介紹到這了,更多相關(guān)Django drf源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Django DRF APIView源碼運行流程詳解
- Django DRF認證組件流程實現(xiàn)原理詳解
- Django DRF路由與擴展功能的實現(xiàn)
- django drf框架自帶的路由及最簡化的視圖
- django drf框架中的user驗證以及JWT拓展的介紹
- Django框架之DRF 基于mixins來封裝的視圖詳解
- DRF跨域后端解決之django-cors-headers的使用
- django DRF圖片路徑問題的解決方法