Django drf請(qǐng)求模塊源碼解析
DRF 框架,全稱為 Django Rest Framework,是 Django 內(nèi)置模塊的擴(kuò)展,用于創(chuàng)建標(biāo)準(zhǔn)化 RESTful API;它利用 ORM 映射數(shù)據(jù)庫,并自定義序列化數(shù)據(jù)進(jìn)行返回,多用于前后端分離項(xiàng)目
項(xiàng)目地址:
https://github.com/encode/django-rest-framework
請(qǐng)求模塊:request對(duì)象
源碼入口
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
)
源碼分析
源碼很簡(jiǎn)單,第1句parser_context = self.get_parser_context(request),我們進(jìn)入方法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', {})
}
上面的代碼的意思是:返回一個(gè)解析的字典以便于Parser.parse()去解析,另外還通過Request對(duì)象添加了上下文request和encoding
第二句返回了一個(gè)Request對(duì)象,點(diǎn)擊進(jìn)入查看

我們可以分析出,內(nèi)部對(duì)request做了二次封裝,_request是一個(gè)HttpRequest對(duì)象,并且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)
意思是如果這個(gè)實(shí)例上不存在一個(gè)屬性,那么我們也會(huì)嘗試將其代理到底層HttpRequest對(duì)象。接下來我們可以通過案例演示
案例演示

我們創(chuàng)建了TestView視圖,視圖函數(shù)中打印了3個(gè)request屬性,并且在response上打了一個(gè)斷點(diǎn),接下來通過url訪問視圖,進(jìn)入斷點(diǎn)如下,

我們可以清楚的看到:
- request是
drf的Request對(duì)象 - request下有
data屬性,query_params屬性,但是沒有GET屬性
上面還有一個(gè)Protected Attributes屬性,里面包含了_request屬性

我們可以看到_request是WSGIHttpRequest對(duì)象,所以它會(huì)有GET屬性,所以我們視圖中打印的request.GET實(shí)際上和request._request.GET是一樣的,因?yàn)?code>request沒有GET屬性,所以它就會(huì)訪問_request中的GET屬性,最后我們查看打印結(jié)果,如下:
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
同樣的,POST請(qǐng)求也是如此,我們?cè)谝晥D中添加POST的請(qǐng)求方式,如下:
def post(self, request, *args, **kwargs):
print(request.POST) # 兼容
print(request._request.POST) # 二次封裝
print(request.data) # 拓展,兼容性最強(qiáng),3種請(qǐng)求方式都可以
return Response("drf post ok")
我們都知道提交數(shù)據(jù)一般有3種方式
- multipart/form-data
- application/x-www-form-urlencoded
- application/json
首先我們使用multipart/form-data提交請(qǐng)求數(shù)據(jù),并請(qǐng)求API

我們查看pycharm打印結(jié)果
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
可以看到multipart/form-data這種請(qǐng)求方式,都能打印出來
接著我們使用application/x-www-form-urlencoded提交請(qǐng)求數(shù)據(jù),并請(qǐng)求API

<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
<QueryDict: {'a': ['1']}>
可以看到application/x-www-form-urlencoded這種請(qǐng)求方式,都能打印出來
最后我們使用application/json提交請(qǐng)求數(shù)據(jù),并請(qǐng)求API

可以看到application/json這種請(qǐng)求方式,只有request.data能打印出來
<QueryDict: {}>
<QueryDict: {}>
{'a': 1}
所以request.data兼容性最強(qiáng)
總結(jié)drf對(duì)request進(jìn)行了二次封裝,request._request就是原生的WSGIRequest原生request的屬性和方法都可以被drf的request對(duì)象直接訪問(兼容)drf請(qǐng)求的所有url拼接參數(shù)均被解析到query_params中,所有的數(shù)據(jù)包均被解析到data中其中post請(qǐng)求,request.data的兼容性最強(qiáng),能兼容前臺(tái)傳輸?shù)?code>json格式的數(shù)據(jù)
到此這篇關(guān)于Django(48)drf請(qǐng)求模塊源碼分析 的文章就介紹到這了,更多相關(guān)Django drf源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python通過getattr函數(shù)獲取對(duì)象的屬性值
這篇文章主要介紹了Python通過getattr函數(shù)獲取對(duì)象的屬性值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
python讀取csv文件并把文件放入一個(gè)list中的實(shí)例講解
下面小編就為大家分享一篇python讀取csv文件并把文件放入一個(gè)list中的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-04-04
python實(shí)現(xiàn)單張圖像拼接與批量圖片拼接
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)單張圖像拼接與批量圖片拼接,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
Python中TCP協(xié)議的探索與實(shí)例解析
網(wǎng)絡(luò)編程在當(dāng)今數(shù)字化世界中扮演著至關(guān)重要的角色,本文將帶你深入了解 Python 中的 TCP 協(xié)議,介紹網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí),并提供豐富的示例代碼,希望對(duì)大家有所幫助2023-12-12

