作者 | ipython
在這一章,你將學(xué)習(xí)Flask應(yīng)用程序不同部分。同時你將編寫和運行你的第一個Flask web應(yīng)用程序。
1、初始化
在這章,你將學(xué)到Flask應(yīng)用程序的不同部分。同時,你將編寫和運行你的第一個Flask web應(yīng)用程序。
所有的Flask應(yīng)用程序都必須創(chuàng)建一個 應(yīng)用程序?qū)嵗?。使用web服務(wù)器網(wǎng)關(guān)接口協(xié)議將所有從客戶端接收的請求傳遞給這個對象處理。這個應(yīng)用程序?qū)嵗褪荈lask類的一個對象,通常使用下面的方式創(chuàng)建:
from flask import Flask
app = Flask(__name__)
Flask類構(gòu)造函數(shù)唯一需要的參數(shù)就是應(yīng)用程序的主模塊或包。對于大多數(shù)應(yīng)用程序,Python的name變量就是那個正確的、你需要傳遞的值。
注:對于Flask開發(fā)者來說,傳給Flask應(yīng)用程序構(gòu)造函數(shù)的name參數(shù)是比較容易弄混淆的。Flask使用這個參數(shù)來確定應(yīng)用程序的根目錄,這樣以后可以相對這個路徑來找到資源文件。
稍后你可以看到更復(fù)雜的應(yīng)用程序?qū)嵗跏蓟?,但是對于簡單?yīng)用程序這些已經(jīng)足夠了。
2、路由和視圖函數(shù)
客戶端例如web瀏覽器發(fā)送 請求 給web服務(wù),進(jìn)而將它們發(fā)送給Flask應(yīng)用程序?qū)嵗?。?yīng)用程序?qū)嵗枰缹τ诟鱾€URL請求需要運行哪些代碼,所以它給Python函數(shù)建立了一個URLs映射。這些在URL和函數(shù)之間建立聯(lián)系的操作被稱之為 路由 。
在Flask應(yīng)程序中定義路由的最便捷的方式是通過顯示定義在應(yīng)用程序?qū)嵗系腶pp.route裝飾器,注冊被裝飾的函數(shù)來作為一個路由。下面的例子會演示怎樣使用裝飾器來申明一個路由:
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
注:裝飾器是Python語言的標(biāo)準(zhǔn)特性;它們可以以不同方式改變函數(shù)的行為。一個常見的模式是使用裝飾器來注冊函數(shù)作為一個事件處理程序。
在上一個示例給應(yīng)用程序的根URL注冊index()函數(shù)作為事件的處理程序。如果這個應(yīng)用程序被部署在服務(wù)器上并綁定了 www.example.com 域名,然后在你的瀏覽器地址欄中輸入 http://www.example.com 將觸發(fā)index()來運行服務(wù)??蛻舳私邮盏降倪@個函數(shù)的返回值被稱為 響應(yīng) 。如果客戶端是web瀏覽器,響應(yīng)則是顯示給用戶的文檔。
類似于index()的函數(shù)被稱作 視圖函數(shù) 。通過視圖返回的響應(yīng)可以是簡單的HTML內(nèi)容的字符串,但它也可以市更復(fù)雜的形式,正如您將看到的。
注:響應(yīng)字符串嵌入在Python代碼中導(dǎo)致代碼難以掌控,在此只是介紹響應(yīng)的概念。你將在第三章學(xué)習(xí)正確的方法來生成響應(yīng)。
如果你注意到你每天使用的一些網(wǎng)站URLs如何形成的,你將會發(fā)現(xiàn)很多都有變量。例如,你的Facebook個人信息頁的URL是 http://www.facebook.com/<username> ,所以你的用戶名是它的一部分。Flask在路由裝飾器中使用特殊的語法支持這些類型的URLs。下面的示例定義了一個擁有動態(tài)名稱組件的路由:
@app.route('/user/<name>')
def user(name):
return '<h1>Hello, %s!</h1>' % name
用尖括號括起來的部分是動態(tài)的部分,所以任何URLs匹配到靜態(tài)部分都將映射到這個路由。當(dāng)視圖函數(shù)被調(diào)用,F(xiàn)lask發(fā)送動態(tài)組件作為一個參數(shù)。在前面的示例的視圖函數(shù)中,這個參數(shù)是用于生成一個個性的問候作為響應(yīng)。
在路由中動態(tài)組件默認(rèn)為字符串,但是可以定義為其他類型。例如,路由/user/<int:id>只匹配有一個整數(shù)在id動態(tài)段的URLs。Flask路由支持int、float和path。path同樣是字符串類型,但并不認(rèn)為斜杠是分隔符,而認(rèn)為它們是動態(tài)組件的一部分。
3、服務(wù)啟動
應(yīng)用程序?qū)嵗幸粋€run方法用于啟動Flask集成的web服務(wù):
if __name__ == '__main__':
app.run(debug=True)
name == 'main'在此處使用是用于確保web服務(wù)已經(jīng)啟動當(dāng)腳本被立即執(zhí)行。當(dāng)腳本被另一個腳本導(dǎo)入,它被看做父腳本將啟動不同的服務(wù),所以app.run()調(diào)用會被跳過。
一旦服務(wù)啟動,它將進(jìn)入循環(huán)等待請求并為之服務(wù)。這個循環(huán)持續(xù)到應(yīng)用程序停止,例如通過按下Ctrl-C。
有幾個選項參數(shù)可以給app.run()配置web服務(wù)的操作模式。在開發(fā)期間,可以很方便的開啟debug模式,將激活 debugger 和 reloader 。這樣做是通過傳遞debug為True來實現(xiàn)的。
注:Flask提供的web服務(wù)并不用于生產(chǎn)環(huán)境。你將在十七章學(xué)習(xí)生產(chǎn)環(huán)境的web服務(wù)。
4、一個完整的應(yīng)用程序
在上一節(jié),你學(xué)習(xí)了Flask web應(yīng)用程序的不同部分,現(xiàn)在是時候?qū)懸粋€了。整個 hello.py 應(yīng)用程序腳本只不過將前面描述的三個部分結(jié)合在一個文件中。應(yīng)用程序示例2-1所示。
示例2-1 hello.py:一個完整的Flask應(yīng)用程序
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '
<h1>Hello World!</h1>
'
if __name__ == '__main__':
app.run(debug=True)
建議:如果你有克隆在GitHub上的應(yīng)用程序,你現(xiàn)在可以運行g(shù)it checkout 2a來切換到這個版本的應(yīng)用程序。
運行應(yīng)用程序之前,請確保你在之前創(chuàng)建的虛擬環(huán)境已經(jīng)是激活狀態(tài)且已安裝Flask?,F(xiàn)在打開你的web瀏覽器并在地址欄輸入 http://127.0.0.1:5000/ 。圖像2-1顯示連接到應(yīng)用程序后的web瀏覽器。
圖像2-1 hello.py Flask應(yīng)用程序
然后輸入以下命令啟動應(yīng)用程序:
(venv) $ python hello.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader
如果你輸入任何其他URL,應(yīng)用程序?qū)⒉恢廊绾尾僮魉⑶覍⒎祷劐e誤代碼404給瀏覽器——當(dāng)你訪問一個不存在的網(wǎng)頁也會得到該錯誤。
示例2-2所示應(yīng)用程序的增強版添加了第二個動態(tài)路由。當(dāng)你訪問這個URI,你應(yīng)該可以看到一個個性的問候。
示例2-2 hello.py:帶有動態(tài)路由的Flask應(yīng)用程序
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '
<h1>Hello World!</h1>
'
@app.route('/user/<name>')
def user(name):
return '
<h1>Hello, %s!</h1>
' % name
if __name__ == '__main__':
app.run(debug=True)
建議:如果你有克隆在GitHub上的應(yīng)用程序,你現(xiàn)在可以運行g(shù)it checkout 2b來切換到這個版本的應(yīng)用程序。
測試動態(tài)路由,確保服務(wù)正在運行隨后訪問 http://localhost:5000/user/Dave 。生成的應(yīng)用程序會使用動態(tài)參數(shù)名響應(yīng)一個定制的問候。嘗試不同的名稱,看看視圖函數(shù)總是生成響應(yīng)基于給定的名稱。圖像2-2展示的一個示例。
圖像2-2 hello.py 動態(tài)路由
原文轉(zhuǎn)自:https://segmentfault.com/a/1190000000730217