Day 6 我們已經成功把第一個 Flask Web App 跑起來了。
目前專案只有:
ai-task-manager/
├── app.py
├── requirements.txt
└── templates/
└── index.html
瀏覽器打開:
http://127.0.0.1:5000
也可以看到:
AI Task Manager
看起來很順。
但我覺得這時候有一件事情比繼續加功能更重要。
就是:
我到底看不看得懂 Claude Code 幫我寫的程式?
如果只是讓 Claude Code 一直幫我生程式,網站確實可能越做越完整,但我自己可能只知道「它可以跑」,卻不知道為什麼可以跑。
所以今天先不加新功能。
先把 app.py 看懂。
目前的內容是:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
程式不長。
但裡面其實已經有幾個 Flask 很重要的概念。
今天就一段一段拆。
from flask import Flask, render_template
這行是在說:
從
flask套件裡,匯入Flask和render_template。
其中:
Flask
是 Flask 提供的類別。
我們會用它建立 Web App。
而:
render_template
是一個函式,用來讀取 HTML 模板。
目前這兩個名稱不是我自己取的。
它們都是 Flask 套件提供的東西。
app = Flask(__name__) 是什麼?接著是:
app = Flask(__name__)
這一行是在建立 Flask 應用程式。
可以先把它拆成兩邊看。
右邊:
Flask(__name__)
是在建立 Flask App。
左邊:
app
則是把建立好的 Flask App 存進變數。
所以這裡的:
app
其實可以自己取名字。
例如:
web = Flask(__name__)
也是可以的。
只是大部分 Flask 專案都習慣寫:
app = Flask(__name__)
後面也會比較容易看懂。
__name__ 又是什麼?這個:
__name__
不是 Flask 自己發明的。
它是 Python 內建的特殊變數。
Python 執行每個檔案時,都會自動幫這個檔案設定 __name__。
如果目前這個檔案是直接被執行:
python app.py
那:
__name__
通常會是:
__main__
Flask 使用 __name__,可以知道目前這個程式所在的位置,之後尋找 templates、static 等資源時會用到。
目前不用把它想得太複雜。
先記得:
__name__
是 Python 自己提供的
就好。
@app.route("/") 是什麼?接下來:
@app.route("/")
這一行是在設定網址路由。
可以先理解成:
當有人打開
/這個網址時,要執行下面的函式。
/ 代表網站首頁。
例如:
http://127.0.0.1:5000/
最後面的 /,就是這裡設定的:
@app.route("/")
如果以後寫:
@app.route("/tasks")
那網址就會變成:
http://127.0.0.1:5000/tasks
route 是固定名稱嗎?這裡的:
route
是 Flask 提供的方法,所以不能隨便改成:
@app.abc("/")
除非真的有一個叫 abc() 的方法。
但是網址裡面的:
/
是我們自己決定的。
例如:
@app.route("/hello")
就可以對應:
http://127.0.0.1:5000/hello
def index(): 又是什麼?下一行:
def index():
這就是一般的 Python 函式。index 這個名字是我自己取的。
例如:
def home():
也可以。
只要上面的路由裝飾器還在:
@app.route("/")
def home():
return render_template("index.html")
首頁一樣可以正常運作。
所以:
index
不是 Flask 固定規定的名稱。
接著:
return render_template("index.html")
這一行是把 HTML 頁面回傳給瀏覽器。
前面已經匯入:
render_template
Flask 會去:
templates/
資料夾裡找:
index.html
所以:
render_template("index.html")
實際上是在找:
templates/index.html
這也是為什麼 Day 6 的 HTML 要放在 templates 裡。
目前整個流程可以畫成:
使用者打開瀏覽器
↓
http://127.0.0.1:5000/
↓
Flask 收到 GET /
↓
@app.route("/")
找到對應函式
↓
執行 index()
↓
render_template("index.html")
↓
讀取 templates/index.html
↓
把 HTML 回傳給瀏覽器
↓
瀏覽器顯示 AI Task Manager
這樣看就比較容易理解。
不是瀏覽器自己跑去打開 index.html。
中間其實是 Flask 先收到請求,再決定要回傳哪個 HTML。
if __name__ == "__main__" 是什麼?最後兩行:
if __name__ == "__main__":
app.run(debug=True)
這裡是 Python 很常看到的寫法。
它的意思可以先理解成:
如果這個檔案是直接被執行,就啟動 Flask。
我們執行:
python app.py
這時:
__name__
會是:
__main__
所以條件成立,接著執行:
app.run(debug=True)
Flask 就開始跑。
假設直接寫:
app.run(debug=True)
也是有可能跑起來。
但之後如果別的 Python 檔案匯入 app.py,app.run() 也會直接被執行。
通常我們不希望這樣。
所以才會用:
if __name__ == "__main__":
限制:
只有直接執行這個檔案時才啟動伺服器。
debug=True 再複習一次Day 6 已經有提到:
app.run(debug=True)
其中:
debug=True
代表開啟 Debug Mode。
開發時主要有兩個方便的地方。
第一個是修改 Python 程式後,Flask 通常會自動重新載入。
第二個是如果程式發生錯誤,會顯示比較完整的錯誤資訊。
所以目前本機開發先保留:
debug=True
整理一下目前 app.py:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
可以先分成兩類。
Flask
render_template
__name__
route
run
這些不是隨便自己取的名稱。
它們有原本的功能。
app
index
"/"
"index.html"
這些可以依照專案需求修改。
例如:
web = Flask(__name__)
@web.route("/home")
def home():
return render_template("home.html")
也是可以的。
只是改完之後,其他相關地方也要一起改。
只看解釋還是有點抽象。
所以我想自己改一個很小的地方。
把:
def index():
改成:
def home():
最後變成:
@app.route("/")
def home():
return render_template("index.html")
存檔之後重新整理瀏覽器。
如果網站還是正常顯示:
AI Task Manager
就代表:
index
真的只是函式名稱。
真正決定首頁網址的是:
@app.route("/")
這種小測試比直接背「index 可以自己取」更容易記住。
接著也可以新增一個簡單路由:
@app.route("/about")
def about():
return "About AI Task Manager"
這次打開:
http://127.0.0.1:5000/about
應該就會看到:
About AI Task Manager
這裡還不用建立新的 HTML。
只是想確認:
不同 route
可以對應不同網址
測完之後,如果不想保留這個 /about,再刪掉就可以。
目前還不需要把它正式做進專案。
以前如果是在一般聊天視窗裡問:
幫我解釋 app.py。
我需要先把 app.py 複製過去。
但現在 Claude Code 就在專案裡。
我可以直接說:
幫我解釋目前的 app.py
它自己就能去讀。
如果後面 app.py 變長,或開始出現:
routes/
services/
models/
這個差別應該會更明顯。
Claude Code 可以幫忙解釋,不代表我看到它的答案就一定要直接相信。
如果有一段看不懂,我還是可以繼續追問:
我還是不懂 Flask(__name__),
請不要講太多 Flask 內部原理,
用一個簡單例子重新解釋。
或者:
為什麼 index.html 一定要放 templates?
如果我真的想放其他資料夾,可以嗎?
與其一次叫它產生一大篇說明,我反而比較喜歡哪裡卡住就問哪裡。
今天完全沒有增加任務管理功能。
只是把 Day 6 建立的 app.py 拆開來看。
目前至少知道:
Flask(__name__)
建立 Flask App
@app.route("/")
設定網址
index()
處理首頁請求
render_template()
讀取 HTML
app.run()
啟動 Flask
這樣下一次 Claude Code 再幫我修改 Flask 程式時,我至少不會只看到一堆完全陌生的東西。
下一篇就開始讓這個只有一個標題的首頁,看起來稍微像一個任務管理網站。