黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

python-django中的APPEND_SLASH實(shí)現(xiàn)方法

系統(tǒng) 2154 0

關(guān)于django中的APPEND_SLASH

APPEND_SLASH 它是啥?

看變量名大概能知道做什么,就是添加斜線,用路由系統(tǒng)那里。

路由文件,只寫了路由關(guān)系代碼

            
......
urlpatterns = [
  url(r'^test/$', views.test),
]
......
          

APPEND_SLASH這個(gè)常量默認(rèn)為True,就是假如你沒有添加斜線,他會(huì)幫你添加上(總體是這樣,具體得看源碼怎么寫的了)

執(zhí)行命名行代碼啟動(dòng)django項(xiàng)目

            
python manage.py runserver
          

目前APPEND_SLASH=True,我們打開瀏覽器的開發(fā)者工具,查看網(wǎng)絡(luò)請(qǐng)求,輸入 127.0.0.1:8000/test 這里我是沒有加斜線的

python-django中的APPEND_SLASH實(shí)現(xiàn)方法_第1張圖片

仔細(xì)看下網(wǎng)絡(luò)請(qǐng)求,我們輸入127.0.0.1:8000/test,看起來只發(fā)送了一次,其實(shí)真實(shí)發(fā)送了兩次請(qǐng)求。

我們繼續(xù)再訪問這個(gè)url: 127.0.0.1:8000/test11 ,看看請(qǐng)求

python-django中的APPEND_SLASH實(shí)現(xiàn)方法_第2張圖片

我們也同樣訪問了一個(gè)url,但是這次和上面不同的是,只發(fā)送了一次請(qǐng)求。

兩次都是發(fā)送一個(gè)get請(qǐng)求,訪問服務(wù)器的一個(gè)資源。

第一次請(qǐng)求的url為 127.0.0.1:8000/test ,我們的路由關(guān)系中是沒有這個(gè)url的,對(duì)沒錯(cuò),如果訪問想要訪問到服務(wù)器的資源必須為這樣的url才行 127.0.0.1:8000/test/ ,雖說這兩個(gè)url看起來差不多,但其實(shí)差很多的。但是第一次請(qǐng)求的url只需在最后加上 / ,就能訪問到資源了,這就是APPEND_SLASH的作用。

第二次請(qǐng)求的url為 127.0.0.1:8000/test11 ,這個(gè)地址也不在我們的路由關(guān)系中,況且加上了 / ,也不能訪問到資源。所以總共發(fā)送了一次,最終返回了404錯(cuò)誤。

先大致總結(jié)下:APPEND_SLASH=True的情況下,先會(huì)根據(jù)前端傳來的url,先檢測(cè)這個(gè)url能不能訪問資源,如果可以訪問的話,那么就去執(zhí)行相應(yīng)的業(yè)務(wù)代碼,最后返回。如果這個(gè)url不能訪問到資源的話,會(huì)判斷這個(gè)url最后有沒有 / ,有 / 的話,則返回404錯(cuò)誤;如果沒有 / 的話,便會(huì)幫你加上 / ,生成一個(gè)新的url,再去檢測(cè)這個(gè)新的url能不能訪問到資源,如果能訪問的話,則返回301的狀態(tài)碼,并將這個(gè)新的url傳到前端,進(jìn)行重定向操作(這就是我們第一次請(qǐng)求出現(xiàn)的情況),如果這個(gè)新的url(幫你加上 / 的)還是不能訪問到資源的話,也會(huì)返回404錯(cuò)誤(這就是我們第二次請(qǐng)求出現(xiàn)的情況)。這就是對(duì)上面出現(xiàn)情況的總結(jié)吧(具體流程還得去看源碼)

那么APPEND_SLASH=False的情況,就不會(huì)幫你加 / ,你前臺(tái)傳怎樣的url,那就用這個(gè)url去訪問資源,能不能訪問還得看你url對(duì)不對(duì)。

在走到路由層之前,請(qǐng)求會(huì)先走到中間件這一層,在這一層就執(zhí)行了上面分析的邏輯

這一個(gè)中間件實(shí)現(xiàn)了上面的邏輯 'django.middleware.common.CommonMiddleware' ,請(qǐng)求來的時(shí)候,會(huì)走這個(gè)中間件的 process_request 方法,下面來看這個(gè)方法寫了什么

python-django中的APPEND_SLASH實(shí)現(xiàn)方法_第3張圖片

看這一句注釋:# Check if a slash should be appended,檢測(cè)是否需要加上斜線

看這個(gè)方法 should_redirect_with_slash ,返回值為bool類型。返回True的情況是,APPEND_SLASH=True,這個(gè)url不是以 / 結(jié)尾的,并且這個(gè)url添加上了 / ,能夠訪問資源的。必須滿足這三種情況,返回值為True,其他情況的話返回就是False。

下面貼上 should_redirect_with_slash 的源碼

            
def should_redirect_with_slash(self, request):
  """
  Return True if settings.APPEND_SLASH is True and appending a slash to
  the request path turns an invalid path into a valid one.
  """
  if settings.APPEND_SLASH and not request.path_info.endswith('/'):
    urlconf = getattr(request, 'urlconf', None)
    return (
      not is_valid_path(request.path_info, urlconf) and
      is_valid_path('%s/' % request.path_info, urlconf)
    )
  return False
          

就說下 is_valid_path 方法有啥作用吧。你可以去看源碼具體了解

is_valid_path 檢測(cè)傳進(jìn)去的url,是否能訪問到資源。(說白了就是判斷這個(gè)url是否存在我們定義的url映射中)

這樣的話,上面這段代碼就很簡(jiǎn)單了。首先判斷APPEND_SLASH,如果為False的。那么這個(gè)方法 should_redirect_with_slash 直接返回False。如果APPEND_SLASH為True的話,再對(duì)請(qǐng)求的url進(jìn)行判斷, request.path_info 它的值并不是一個(gè)完整的url,而是ip+端口后面的那一部分(也就是例子中的 /test ),判斷它是否以斜線( / )結(jié)尾的,如果是的話,那么 not request.path_info.endswith('/') 整體就為False,所以if判斷后面的表達(dá)式就為False,最終返回了False。如果不是以斜線( / )結(jié)尾的話,那么if后面的表達(dá)式就為True,那么繼續(xù)執(zhí)行條件為真的代碼塊,這個(gè)代碼塊最終返回了一個(gè)表達(dá)式的結(jié)果,這個(gè)表達(dá)式類型是這樣 bool and bool。也就是根據(jù)方法 is_valid_path d的返回值進(jìn)行判斷的,如果 request.path_info (代碼能分析到這里說明它不是以斜線結(jié)尾的),首先判斷這個(gè)值能不能在我們寫的路由關(guān)系映射中存不存在。存在的話,方法 is_valid_path 返回真,那么 not True 就為False,and左邊的表達(dá)式為False,整體的表達(dá)式就為False,所以最終返回的就是False。如果 request.path_info 的值在路由關(guān)系映射中不存在,那么and左邊的表達(dá)式為True,那就繼續(xù)看and右邊表達(dá)式的布爾值。and右邊還是調(diào)用了方法 is_valid_path ,只不過傳的參數(shù)是 request.path_info + / ,如果在路由映射中存在,那么最終返回True,如果不存在,那么就返回了False了。

should_redirect_with_slash 方法分析完畢,繼續(xù)看源碼

            
# Check if a slash should be appended
if self.should_redirect_with_slash(request):
  path = self.get_full_path_with_slash(request)
else:
  path = request.get_full_path()
          

后面根據(jù) should_redirect_with_slash 方法的返回值,做了不同的操作。不嚴(yán)格來說,不管True還是False,最終執(zhí)行了 requests.get_full_path 這個(gè)方法,只不過傳入的參數(shù)不同的,最終返回了一個(gè)完整的url請(qǐng)求地址。

繼續(xù)往下看

            
# Return a redirect if necessary
if redirect_url or path != request.get_full_path():
  redirect_url += path
  return self.response_redirect_class(redirect_url)
          

如果if后面的表達(dá)式為True的話,最終稿返回了一個(gè)狀態(tài)碼為301的Httpresponse對(duì)象,這個(gè)對(duì)象里帶這一個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)就是在原url基礎(chǔ)上加上斜線( / )的新url,前端接收到狀態(tài)碼為301的響應(yīng),則會(huì)繼續(xù)請(qǐng)求響應(yīng)中攜帶的新地址。為False的話,返回默認(rèn)返回None。

django的中間件會(huì)根據(jù)每個(gè)中間件里的process_request方法或者process_response方法不同的返回值會(huì)執(zhí)行相應(yīng)的操作,具體操作不說了,不是這個(gè)知識(shí)點(diǎn)的內(nèi)容。

那么中間件的 process_request 返回None的話,則會(huì)執(zhí)行下一個(gè)中間件的 process_request 的方法。如果返回的是HttpResponse對(duì)象的話,則不會(huì)繼續(xù)執(zhí)行下一個(gè)中間件的 process_request 方法,則會(huì)執(zhí)行 process_response 方法。具體從哪個(gè)中間件執(zhí)行和django的版本有關(guān)系,反正是不會(huì)執(zhí)行路由對(duì)應(yīng)的視圖代碼的代碼,會(huì)直接返回給前端HttpResoonse對(duì)象。

好了,關(guān)于APPEND_SLASH的知識(shí)總結(jié)完畢。APPEND_SLASH它默認(rèn)為True,如果想要修改的話,需要在settings.py文件中定義這個(gè)常量,賦值為False,這樣就可以覆蓋原django中配置文件里對(duì)應(yīng)的常量了。至于django內(nèi)部怎么操作的,下次再總結(jié)吧

最后還是補(bǔ)個(gè)圖吧,我把APPEND_SLASH設(shè)置為False,訪問 127.0.0.1:8000/test

python-django中的APPEND_SLASH實(shí)現(xiàn)方法_第4張圖片

如果你設(shè)置了APPEND_SLASH為False,訪問上面這個(gè)url,還是能訪問到頁面的話,清理下瀏覽器的緩存,就可以了

總結(jié)

以上所述是小編給大家介紹的python-django中的APPEND_SLASH實(shí)現(xiàn),希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論