你的第一個Django程式

昀溪發表於2018-09-12

本文使用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才會自動預設加上“/”。

REST AP設計

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去繼續匹配。

相關文章