python-django中的APPEND_SLASH實現

来源:https://www.cnblogs.com/zhuchunyu/archive/2019/06/20/11062044.html
-Advertisement-
Play Games

關於django中的APPEND_SLASH 它是啥? 看變數名大概能知道做什麼,就是添加斜線,用路由系統那裡。 路由文件,只寫了路由關係代碼 APPEND_SLASH這個常量預設為True,就是假如你沒有添加斜線,他會幫你添加上(總體是這樣,具體得看源碼怎麼寫的了) 執行命名行代碼啟動django ...


關於django中的APPEND_SLASH

APPEND_SLASH 它是啥?

看變數名大概能知道做什麼,就是添加斜線,用路由系統那裡。

路由文件,只寫了路由關係代碼

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

APPEND_SLASH這個常量預設為True,就是假如你沒有添加斜線,他會幫你添加上(總體是這樣,具體得看源碼怎麼寫的了)

執行命名行代碼啟動django項目

python manage.py runserver

目前APPEND_SLASH=True,我們打開瀏覽器的開發者工具,查看網路請求,輸入127.0.0.1:8000/test 這裡我是沒有加斜線的

仔細看下網路請求,我們輸入127.0.0.1:8000/test,看起來只發送了一次,其實真實發送了兩次請求。

我們繼續再訪問這個url:127.0.0.1:8000/test11,看看請求

我們也同樣訪問了一個url,但是這次和上面不同的是,只發送了一次請求。

兩次都是發送一個get請求,訪問伺服器的一個資源。

第一次請求的url為127.0.0.1:8000/test,我們的路由關係中是沒有這個url的,對沒錯,如果訪問想要訪問到伺服器的資源必須為這樣的url才行127.0.0.1:8000/test/,雖說這兩個url看起來差不多,但其實差很多的。但是第一次請求的url只需在最後加上/,就能訪問到資源了,這就是APPEND_SLASH的作用。

第二次請求的url為127.0.0.1:8000/test11,這個地址也不在我們的路由關係中,況且加上了/,也不能訪問到資源。所以總共發送了一次,最終返回了404錯誤。

先大致總結下:APPEND_SLASH=True的情況下,先會根據前端傳來的url,先檢測這個url能不能訪問資源,如果可以訪問的話,那麼就去執行相應的業務代碼,最後返回。如果這個url不能訪問到資源的話,會判斷這個url最後有沒有/,有/的話,則返回404錯誤;如果沒有/的話,便會幫你加上/,生成一個新的url,再去檢測這個新的url能不能訪問到資源,如果能訪問的話,則返回301的狀態碼,並將這個新的url傳到前端,進行重定向操作(這就是我們第一次請求出現的情況),如果這個新的url(幫你加上/的)還是不能訪問到資源的話,也會返回404錯誤(這就是我們第二次請求出現的情況)。這就是對上面出現情況的總結吧(具體流程還得去看源碼)

那麼APPEND_SLASH=False的情況,就不會幫你加/,你前臺傳怎樣的url,那就用這個url去訪問資源,能不能訪問還得看你url對不對。

在走到路由層之前,請求會先走到中間件這一層,在這一層就執行了上面分析的邏輯

這一個中間件實現了上面的邏輯 'django.middleware.common.CommonMiddleware',請求來的時候,會走這個中間件的process_request方法,下麵來看這個方法寫了什麼

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

看這個方法should_redirect_with_slash,返回值為bool類型。返回True的情況是,APPEND_SLASH=True,這個url不是以/結尾的,並且這個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 檢測傳進去的url,是否能訪問到資源。(說白了就是判斷這個url是否存在我們定義的url映射中)

這樣的話,上面這段代碼就很簡單了。首先判斷APPEND_SLASH,如果為False的。那麼這個方法should_redirect_with_slash直接返回False。如果APPEND_SLASH為True的話,再對請求的url進行判斷,request.path_info它的值並不是一個完整的url,而是ip+埠後面的那一部分(也就是例子中的/test),判斷它是否以斜線(/)結尾的,如果是的話,那麼not request.path_info.endswith('/') 整體就為False,所以if判斷後面的表達式就為False,最終返回了False。如果不是以斜線(/)結尾的話,那麼if後面的表達式就為True,那麼繼續執行條件為真的代碼塊,這個代碼塊最終返回了一個表達式的結果,這個表達式類型是這樣 bool and bool。也就是根據方法is_valid_pathd的返回值進行判斷的,如果request.path_info(代碼能分析到這裡說明它不是以斜線結尾的),首先判斷這個值能不能在我們寫的路由關係映射中存不存在。存在的話,方法is_valid_path返回真,那麼not True就為False,and左邊的表達式為False,整體的表達式就為False,所以最終返回的就是False。如果request.path_info的值在路由關係映射中不存在,那麼and左邊的表達式為True,那就繼續看and右邊表達式的布爾值。and右邊還是調用了方法is_valid_path,只不過傳的參數是request.path_info + /,如果在路由映射中存在,那麼最終返回True,如果不存在,那麼就返回了False了。

should_redirect_with_slash方法分析完畢,繼續看源碼

# 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()

後面根據should_redirect_with_slash方法的返回值,做了不同的操作。不嚴格來說,不管True還是False,最終執行了requests.get_full_path這個方法,只不過傳入的參數不同的,最終返回了一個完整的url請求地址。

繼續往下看

# 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後面的表達式為True的話,最終稿返回了一個狀態碼為301的Httpresponse對象,這個對象裡帶這一個數據,這個數據就是在原url基礎上加上斜線(/)的新url,前端接收到狀態碼為301的響應,則會繼續請求響應中攜帶的新地址。為False的話,返回預設返回None。

django的中間件會根據每個中間件里的process_request方法或者process_response方法不同的返回值會執行相應的操作,具體操作不說了,不是這個知識點的內容。

那麼中間件的process_request返回None的話,則會執行下一個中間件的process_request的方法。如果返回的是HttpResponse對象的話,則不會繼續執行下一個中間件的process_request方法,則會執行process_response方法。具體從哪個中間件執行和django的版本有關係,反正是不會執行路由對應的視圖代碼的代碼,會直接返回給前端HttpResoonse對象。

好了,關於APPEND_SLASH的知識總結完畢。APPEND_SLASH它預設為True,如果想要修改的話,需要在settings.py文件中定義這個常量,賦值為False,這樣就可以覆蓋原django中配置文件里對應的常量了。至於django內部怎麼操作的,下次再總結吧

最後還是補個圖吧,我把APPEND_SLASH設置為False,訪問127.0.0.1:8000/test

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 劉老師說這塊很重要。。。。。 應該是很重要,大概看了一下,這裡面關於views中函數作用,大概看來可能就是相應請求,傳入數據和跳轉,基本功能上貌似這些框架都差不多吧(其實我並沒用過3個框架以上。。。。) 從功能上想,網站必然包含了許多實現具體功能和數據展示的頁面,而現在在做的就是構成這些。 那麼一個 ...
  • 本文例子完整源碼地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword 《【好書推薦】《劍指Offer》之軟技能》 《【好書推薦】《劍指Offer》之硬技能(編程題1~6)》 《【好書推薦】《劍 ...
  • Java語言的環境搭建 1.什麼是JDK和JRE? JDK(Java Development Kit:Java開發工具包): JDK是提供給Java開發人員使用的,其中包含了java的開發工具,也包括了JRE。所以安裝了JDK,就不用再單獨安裝JRE了。其中的開發工具有編譯工具(javac.exe) ...
  • 好久不見,風水輪流轉,我竟然寫寫寫python了 近日有個小需求,要求收集統計一些信息上報,並直接在後臺控制台列印,寫入日誌 為了美觀,需要以表格形式展現數據,形如 雖說可以用 prettytable 實現這個效果,不過還得安裝這個庫,需求比較簡單就不考慮安裝第三方依賴了,所以得自己寫 照著這個圖, ...
  • 分析出現no Session錯誤的原因以及給出解決方案: 使用SpringMVC + JSON數據返回時,經常會出現no Session的錯誤: 報錯原因:因為懶載入在提取關聯對象的屬性值的時候發現EntityManager已經被關閉,就報no session錯誤。 控制器類中的方法上添加了@Res ...
  • 策略模式:定義了不同的演算法,分別分裝起來,讓他們可以互相替換,即使演算法變化了,也不會影響到使用演算法的用戶 首先定義一個抽象演算法類,有兩個類繼承了這個抽象類,重寫了AlgorithmInterface()方法 用一個context類來維護對抽象演算法類Strategy對象的引用(重點) 測試類1 但是從 ...
  • 在 Spring Boot 中集成 Shiro,並使用 JWT 進行介面認證。 為了統一對 Token 進行過濾,所以自定義了一個 過濾器。 期間遇到了以下幾個問題,這裡逐一進行記錄,以備日後查閱。 問題一:JwtTokenFilter 無法使用 @Autowired 因為自定義了一個 JWT To ...
  • IDEA設置取消自動顯示參數提示 最近在使用IDEA的過程中,發現方法中一直顯示形參名的提示,無法選中,也無法刪除,基於不同人的使用習慣不同,有的人不喜歡這種提示,我也在網上尋找各種解決方案,由於搜索關鍵詞不對,一直沒能解決,不過好基友及時幫助,順利解決,多謝我的大副。 取消參數提示之前,我的方法中 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...