位置:
創(chuàng)新互聯(lián)長(zhǎng)期為上千客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為天元企業(yè)提供專業(yè)的成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè),天元網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。
1.找到自己項(xiàng)目用的解釋器存儲(chǔ)位置
H:\pythonProject\Lib\site-packages\django\views\generic\base.py
在base.py里有一個(gè)View類
2.也可以通過(guò)from django.views import View 按住ctrl點(diǎn)擊View會(huì)直接跳到該類的位置
CBV形式的路由
path(r'^login/',views.MyLogin.as_view())
CBV形式的視圖函數(shù)
from django.views import View
class MyLogin(View):
def get(self,request): #get請(qǐng)求時(shí)執(zhí)行的函數(shù)
return render(request,'form.html')
def post(self,request): #post請(qǐng)求時(shí)執(zhí)行的函數(shù)
return HttpResponse('post方法')
CBV源碼分析:
當(dāng)上述的login請(qǐng)求來(lái)了之后---》會(huì)執(zhí)行后面的views.MyLogin.as_view()---》這個(gè)地方應(yīng)該放的是函數(shù)的內(nèi)存地址,views.MyLogin.as_view()執(zhí)行完,是個(gè)函數(shù)內(nèi)存地址,---views.MyLogin.as_view()會(huì)去views.py中找到MyLogin這個(gè)類,然后找as_view()方法,發(fā)現(xiàn)沒(méi)有--》去其父類中找就是View類中找---》執(zhí)行as_view()方法最終返回的是一個(gè)View類內(nèi)部的一個(gè)view函數(shù)內(nèi)存地址---》然后django框架會(huì)自動(dòng)給view這個(gè)函數(shù)加括號(hào)調(diào)用,再傳入request這個(gè)參數(shù)--->而view這個(gè)內(nèi)部函數(shù)返回的是return handler(request, *args, **kwargs)就是對(duì)應(yīng)類中g(shù)et或者post方法
as_view()方法分析:
@classonlymethod # 1.這個(gè)as_view是一個(gè)類方法,所以用類調(diào)用時(shí),會(huì)自動(dòng)把調(diào)用的類傳入給這個(gè)函數(shù)的cls
def as_view(cls, **initkwargs):
"""Main entry point for a request-response process."""
# 2.因?yàn)閡rl那邊沒(méi)有傳參,所以initkwargs為空,先忽略該層代碼
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError(
"The method name %s is not accepted as a keyword argument "
"to %s()." % (key, cls.__name__)
)
if not hasattr(cls, key):
raise TypeError(
"%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key)
)
# 3.執(zhí)行該view函數(shù)
def view(request, *args, **kwargs): # request是當(dāng)次請(qǐng)求的數(shù)據(jù)
# 5.cls是當(dāng)前調(diào)用的類MyLogin,cls加括號(hào)產(chǎn)生對(duì)象給了self,這里現(xiàn)在self就是類MyLogin產(chǎn)生的對(duì)象
self = cls(**initkwargs)
self.setup(request, *args, **kwargs)
if not hasattr(self, "request"):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
# 6.view函數(shù)返回了self.dispatch(request, *args, **kwargs)方法,
# self本身沒(méi)有dispatch方法,就去MyLogin中找,MyLogin沒(méi)有就去View類中找,找到了
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs
# __name__ and __qualname__ are intentionally left unchanged as
# view_class should be used to robustly determine the name of the view
# instead.
view.__doc__ = cls.__doc__
view.__module__ = cls.__module__
view.__annotations__ = cls.dispatch.__annotations__
# Copy possible attributes set by decorators, e.g. @csrf_exempt, from
# the dispatch method.
view.__dict__.update(cls.dispatch.__dict__)
# Mark the callback if the view class is async.
if cls.view_is_async:
view._is_coroutine = asyncio.coroutines._is_coroutine
# 4.as_view返回的是該函數(shù)內(nèi)部的view函數(shù)內(nèi)存地址,所以具體讀下view函數(shù)就行
return view
上述as_view()方法返回了一個(gè)dispatch方法,dispatch方法分析:
# 1.dispatch將MyLogin這個(gè)類產(chǎn)生的對(duì)象self和request請(qǐng)求對(duì)象傳入了dispatch
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
# 2.判斷request.method方法在不在http_method_names里,ttp_method_names對(duì)象里沒(méi)有最后去View類里找到了
if request.method.lower() in self.http_method_names:
# 3.通過(guò)getattr方法反射,self.http_method_not_allowed這個(gè)就當(dāng)沒(méi)有前面的方法時(shí)的一個(gè)默認(rèn)值
# handler最后得到的就是MyLogin中定義的get或者post方法的內(nèi)存地址
handler = getattr(
self, request.method.lower(), self.http_method_not_allowed
)
else:
handler = self.http_method_not_allowed
# 4.最后這個(gè)方法將handler加括號(hào),再傳入request參數(shù)調(diào)用的結(jié)果返回出去==執(zhí)行了MyLogin的get或者post方法
return handler(request, *args, **kwargs)
網(wǎng)站標(biāo)題:django中CBV視圖模式的View源碼分析
瀏覽路徑:http://redsoil1982.com.cn/article4/dsogcoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、定制開(kāi)發(fā)、做網(wǎng)站、關(guān)鍵詞優(yōu)化、Google、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容