本文使用Pycharm、Django 2.0.9、Python 3.6環境,本文大綱
- 建立Django專案
- 建立頁面
- 什麼是URLconf和ROOT_URLCONF
- Django怎麼處理URL請求
- 關於URL尾部的“/” 反斜線
1. 建立一個Django專案
Application name如果填寫會自動幫你建立一個APP,而且APP是必須的,就算你用命令列去建立一個專案也需要再次使用命令建立APP。勾選Enable Django admin,這個後面也會用到。下面是預設的結構。
我們先把下面的內容註釋掉,因為還用不到資料庫。
啟動你的專案
點選連結你會看到下面的內容
2. 你的第一個頁面
再次啟動專案,不過這次你點選以後會出現404錯誤,你在URL中輸入,將會看到你所期待的頁面。
這時候你可能有一些疑問,我必須要輸入/hello麼,如果我需要輸入127.0.0.1:8000就直接看到Hello world頁面怎麼辦?畢竟網站都是有一個預設主頁不想輸入下一級?這時候我們就需要修改URL配置了。
這時候無論你是否輸入/hello都會顯示這個頁面,如下圖
URL中什麼都不加也就是網站的根目錄其實也根配置其他URL一樣需要些一個匹配模式,這個模式就是空。可能細心的同學發現我這裡的URL匹配模式中沒有了^和$,包括網站根目錄也僅僅是一對引號而不是之前的’^$’這種形式。這是在Django 2.0開始發生的變化,2.0以前都是需要加^和$的。但是這裡有個問題這裡的URL不是正則型別的不是正則就很容易匹配到多個,如果我想使用正則型別的怎麼辦?看下圖:
同樣還是主頁,這裡我們用了正則的寫法效果還是一樣的,這個寫法就和Django 1.x裡面一樣了,只是這裡用了re_path,而且在Django 2.x中要想使用支援正則的URL匹配必須使用這個。
現在我們要討論幾個問題
2.1 什麼是URLconf和ROOT_URLCONF
一個URL配置檔案也就是上面這樣的,用於配置URL匹配模式的檔案就是URLconf。那什麼是ROOT_URLCONF呢?
在專案層級的settings.py檔案中有一個ROOT_URLCONF配置選項,這個選項又指向了預設專案層級自動生成的urls.py這個URLconf檔案。其實這個ROOT_URLCONF就是告訴DJANGO從哪裡開始去找匹配你輸入的URL的匹配模式,當第一個匹配到之後就執行對應的動作。如果一直找不到就返回404.
2.2 Django是怎麼處理請求的呢
比如你輸入 http://127.0.0.1:8000/hello的時候它怎麼就能返回你所期待的內容呢?其實就像上面的ROOT_URLCONF說的那樣,它指向了一個包含URL匹配模式得URL配置檔案,這些檔案同時還可以再包含其他URL配置檔案,那麼Django就從ROOT_URLCONF配置的地方開始載入URL配置檔案,然後逐一去匹配,找到第一個匹配的就執行對應的動作,如果找不到就返回404.
當輸入/hello時就匹配到了這條,然後去執行hello這個函式,這個函式定義在mysite.views中
這個函式要執行的具體內容是做一個HTTP響應,返回內容是Hello world。就是這樣一個過程。簡單一句話URL的配置就是把HTTP請求中的URL對映到具體的Python函式上。
直白一點說請求/hello Django將會呼叫mysite.views.hello(request),如果有引數,引數也會被傳遞進來,至於引數怎麼傳遞之後在介紹。
2.3 關於URL尾部的“/”
這個“/”是必須的嗎?我好像輸入URL時也沒有輸入這個它自己怎麼就給我加上了呢。對於URL來說末尾有沒有“/”無所謂,但是到底需不需要是你自己來決定的。預設情況下雖然你不輸入“/”django會自動給你加上,但至於能不能訪問到你期望的內容就要看你的URL配置是怎樣的。
我們的URL配置是這樣的 “hello/” 而且Django預設會自動在末尾增加“/”如果你沒輸入的話,所以這種情況下你在瀏覽器中是否輸入“/”都會訪問到你所期待的網頁。但如果你這個時候把你URL配置更改一下如下圖:(去掉“/”)
這時候由於django預設自動在末尾增加“/”所以這時候你就看不到那個頁面了,將會得到404.
為什麼會這樣呢?很顯然 http://127.0.0.1:8000/hello 和 http://127.0.0.1:8000/hello/ 是兩個URL,後者無法被URL配置檔案匹配到啊,所以你看它給你的提示第三項就說的很明白了。如果我就不想要這個“/”那應該怎麼辦呢?修改settings.py檔案,怎講下面的內容就禁止自動在末尾增加“/”。
這時候你再訪問http://127.0.0.1:8000/hello 這個URL就可以訪問到了。
但是如果你這時候訪問http://127.0.0.1:8000/hello/ 這個就會得到404,為什麼?匹配不到啊。我們再次修改一下URL配置
views.py中增加一個方法
再次訪問
所以URL配置中的URL末尾是否包含“/”則是根據喜好都可以。不過根據REST原則“/”只表示分級無特殊意義,所以在URL末尾不建議增加“/”.不過對於傳統WEB頁面來說加與不加都表示同一資源也就是顯示同一結果,所以django才會自動預設加上“/”。
2.4 難道所有的URL配置都寫在預設的urls.py檔案中嗎?
顯然不是這就用到一個include函式了。通常情況下每一個APP都有自己的URL配置檔案。
mysite是我們的APP,它下面並沒有配置URL的地方, 其實URL配置檔案就是一個.py檔案沒有什麼特殊的,我們手動建立一個就行。
空空如也的檔案,需要寫什麼呢?照貓畫虎,參照之前那個預設生成的urls.py就可以。先說一下需求,所有關於mysite這個APP的URL全部在APP裡面的URL配置檔案中配置。我們先看這個我們新建的URL配置怎麼寫:
修改預設的url.py檔案
到這裡就修改完畢。結果就是輸入 http://127.0.0.1:8000 結果不變還是我們定義的主頁,然後 http://127.0.0.1:8000/mysite/hello 則顯示mysite.views.hello函式執行結果。如下圖:
雖然上面兩個URL顯示結果一樣(因為執行的都是相同的東西),但我們的目的是為了說明URL的引入以及不同APP的URL應該在APP裡面設定而不是都寫到預設生成的urls.py檔案中。
Include()函式的作用就是允許引入其他的URLconf設定,當Django遇到帶有include()的URL匹配是,如果匹配到那麼它會截斷匹配的內容將剩餘的字串傳送到include()裡面的URL配置中繼續匹配。
http://127.0.0.1:8000/mysite/hello 在預設的URL配置檔案中匹配到/mysite/就截斷,然後將hello傳送到mystie裡面的urls.py去繼續匹配。