0%

Flask 筆記 | 路由

路由是屬於網路層 (network layer) 的概念,是資料封包從來源走到目的地時經過的路徑,路由器會根據資料的 IP 位址決定最佳、最穩定或是傳輸效率最大化的傳送路徑。在 Flask 中,路由則指的是將網址路徑對應到某個處理函式的行為。

基礎路徑設定

Flask 路由與路徑的基本語法如下所示:

1
2
3
@app.route("路徑")
def 處理函式名稱(參數名稱):
處理邏輯區塊

假設網址中有 /data 這個路徑,透過以下方式,可以將 /data 綁定到 handleData 處理函式上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
return "Hello, Flask"

# 建立路徑 /data 對應到的處理函式
@app.route("/data")
def handleData():
return "This is data."

app.run()

執行程式後,進入 http://127.0.0.1:5000/data ,即可看到以下畫面。

路由範例

圖 1:路由範例

如果嘗試進入未指定的路徑,則會顯示 Not Found,從字面意義不難看出就是因為這個路徑不存在,無法找到對應的頁面以供顯示。

訪問未指定路徑

圖 2:訪問未指定路徑

動態路由 (Dynamic Route) 設定

基本的路由可以接受參數,但是如果想要接受的變數是變動的,也就是可以根據使用者輸入的內容,讓伺服器執行對應的動作,那麼就需要使用動態路由

類型 路由 對應網址 說明
靜態路由 /hello /hello 只有固定一種網址能對應這個函式
動態路由 /user/<name> /user/david/user/alice name 是變數,可傳入不同值
1
2
3
@app.route("固定字首/<參數名稱>")
def 處理函式名稱(參數名稱):
處理邏輯區塊

例如我們在 /user 這個路徑下,接受 <username>,此時 Flask 會自動從網址擷取字串,傳給 handleUser 中的 username 參數。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
return "Hello, Flask"

# 建立動態路徑 /user/使用者名稱 對應到的處理函式
@app.route("/user/<username>")
def handleUser(username):
return f"Hello, {username}!"

app.run()

例如使用者訪問 /user/Anthony,畫面就會顯示 Hello, Anthony!

動態路由

圖 3:動態路由

但注意到,Flask 預設所有 <參數> 都是字串型別,如果我們需要將參數進行轉換,就需要使用型別轉換:

1
@app.route("/路徑/<型別:參數名稱>")
型別 說明
string 預設型別。匹配任意字串(不含 /
int 只接受整數(例如:42
float 接受浮點數(例如:3.14
path 和 string 類似,但可以包含 /(適合抓取子路徑)
uuid 接受 UUID 格式的字串(例如:6fa459ea-ee8a-3ca4-894e-db77e160355e

例如建立一個路徑 /square,並對應到 square 函式,功能為將傳遞進去的數字平方後顯示在畫面上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
return "Hello, Flask"

# 動態路徑:型別轉換
@app.route("/square/<int:num>")
def square(num):
return f"{num} squared is {num * num}"

app.run()
動態路由型別轉換

圖 4:動態路由型別轉換

多路由綁定單一處理函式

前面路由的設計基本上是一對一的關係,也就是路由僅將一個路徑綁定到一個函式上。但若今天一個函式的功能十分完整,或是重複性極高,可以提供多個路徑使用,Flask 允許為同一個函式指定多個路由路徑,無論使用者輸入哪個 URL,都會被導向執行同一段程式碼。

為什麼要用多路由對應

  • 提高使用者體驗:有些使用者會習慣輸入 / 作為首頁,有些則可能輸入 /index。如果只設定其中一條路由,另一條就會顯示 404 錯誤。透過綁定多個路由,可以避免這種使用習慣上的落差,讓使用者無論輸入哪一種路徑都能正確導向頁面。
  • 向後相容 (backward compatibility):當網站經過改版、重新命名或調整 URL 結構時,舊有的網址可能會被移除或改變。例如,原本的首頁是 /home,後來改為 /,這時仍可保留 /home 的路由,以避免舊有書籤或搜尋引擎索引失效,維持舊網址的可用性。
  • 統一處理邏輯:有時候,不同的路徑實際上是為了表示相同的功能或內容。與其為每條路徑撰寫一份幾乎一樣的程式碼,不如將它們都綁定到同一個函式。這樣不僅簡化維護,也能讓應用程式的邏輯更一致、更清晰。

多裝飾器疊加

最常見的寫法是直接在處理函式上疊加路由處理的裝飾器:

1
2
3
4
5
6
@app.route("路徑 1")
@app.route("路徑 2")
...
@app.route("路徑 n")
def 處理函式名稱(參數名稱):
處理邏輯區塊

當使用者訪問 路徑 1路徑 2路徑 n,Flask 都會呼叫該函式。

傳入 list

上述的寫法雖然方便,但若對應的路徑過多,程式碼會顯得十分混亂與冗長,編輯與維護起來很麻煩。因此可以使用 list 傳入需要的路徑

1
2
3
@app.route(["路徑 1", "路徑 2", ... "路徑 n"])
def 處理函式名稱(參數名稱):
處理邏輯區塊

這種寫法多用於需要動態產生或維護路由清單的場景。