第2章 Flask快速上手
Flask是一個使用Python編寫的輕量級Web應用架構。何謂Web應用架構?Web應用架構(Web application framework)是一種開發架構,用來支援動态網站、網絡應用程式及網絡服務的開發。使用Web應用架構可以節約項目開發的時間和成本。Web開發中有一些共同的功能已經實作了,共同的功能指的是資料庫驅動、網頁模闆引擎、Session和Cookie等基礎功能,開發設計人員隻要使用架構提供的方法,就可以快速高效地進行Web應用開發。Flask架構誕生于2010年,其作者為Armin Ronacher。本來這個項目隻是作者在愚人節的一個惡作劇,後來該架構受到了廣大開發者的喜愛,進而成為一個正式的項目。本章主要介紹Flask的基礎知識、URL傳遞參數和URL反轉等内容。
本章主要涉及的知識點有:
- Web初步知識;
- Flask程式的基本結構;
- URL傳遞參數;
- URL反轉。
2.1 Web基礎知識
Web(World Wide Web)即全球廣域網,也稱為網際網路,它是一種基于超文本和HTTP協定的、全球性的、動态互動的、跨平台的分布式圖形資訊系統,是建立在網際網路上的一種網頁浏覽互動服務,為通路者在網際網路上查找和浏覽資訊提供了圖形化的直覺人機互動接口界面,其中的文檔和超連結的組合更是将網際網路上的資訊流節點組織成一個互為聯系的網絡格子狀結構。
網際網路的工作原理是:當你請求一個網絡資源的時候,應該在浏覽器上輸入所要通路網頁的統一資源定位符(Uniform Resource Locator,URL),當然,也可以通過超連結方式連結定位到要請求的那個網頁或靜/動态資源。之後是對URL根據分布于全球的網際網路域名解析系統的資料庫進行查詢解析,并根據解析結果決定通路哪一個IP位址對應的伺服器。接下來是向對應的Web伺服器發出一個HTTP請求,相應的Web伺服器接收HTTP請求後,調用相應的Web應用處理請求,然後Web伺服器再将響應結果(響應結果指的是圖檔、超文本标記語言,即HTML、JavaScript和視訊等資源)傳回給用戶端浏覽器。Web工作原理如圖2.1所示。

通常的URL一般由傳輸協定名、資源所在的主機名或IP位址、網絡服務程式的端口号和(目錄)檔案名等幾個部分組成,即:
URL=傳輸協定+主機名+端口号+(目錄)檔案名。
傳輸協定一般是http(HyperText Transfer Protocol,超文本傳輸協定)或https(HyperText Transfer Protocol over Secure Socket Layer,安全套接字層超文本傳輸協定)。主機名這裡主要指服務(www)+域名(如:google.com)。端口号是可選的,沒有給出的話,預設端口一般是指80号端口(http協定使用的80端口,https協定使用的443端口)。目錄的出現是在網站結構複雜時,某些資源會放到某個目錄下或若幹個目錄下,這樣就構成了檔案的路徑。檔案名精确地指定了要通路的Web頁面。未指定檔案名時,處理請求的Web伺服器會根據伺服器本身的設定查找出預設的檔案,如index.html、default.jsp等。
2.2 第一個Flask Web程式
Flask是一個基于Python語言的微型Web架構。之是以被稱為微型,是因為其核心非常小,但是該Web架構簡約而不簡單,具有很強的擴充能力。本節介紹如何編寫和運作第一個Flask Web應用程式。
2.2.1 安裝Flask架構
要使用Flask架構,必須先安裝Flask。安裝主要方式有兩種。
1.在PyCharm中安裝Flask
(1)執行File | Settings指令,如圖2.2所示。
(2)在上一步操作基礎上,繼續執行Project:untitled(untitled為工程名,要根據實際的工程名來選擇)|Project Interpreter,如圖2.3所示。
(3)單擊圖2.3中的“+”号按鈕後,彈出如圖2.4所示對話框,在輸入框中輸入Flask,然後回車。
(4)安裝成功以後,如圖2.5所示。
2.用pip方式安裝Flask
筆者的虛拟環境位址為J:flask-venvvenv,在cmd下按以下步驟操作:
(1) cd j:
(2) cd J:\flask-venv\venv\Scripts
(3) activate
上面3個指令的每個指令輸入完後都需要回車。執行完這3個指令後,表示成功激活目前虛拟環境。在(venv)J:flask-venvvenvScripts>下輸入pip install Flask,即:
(venv)J:\flask-venv\venv\Scripts> pip install Flask
然後回車,即可安裝Flask了。
2.2.2 在Flask中輸出Hello World
所有的Flask程式都必須建立一個程式執行個體。Web伺服器使用一種名為Web伺服器網關接口(Web Server Gateway Interface,WSGI)的協定,把接收自用戶端的所有請求都轉給這個對象進行處理。程式執行個體是Flask類的對象,經常使用下述代碼建立:
from flask import Flask
app = Flask(__name__)
from flask import Flask這行代碼表示從Flask架構中引入Flask對象。app = Flask(__name__)這行代碼表示傳入__name__這個變量值來初始化Flask對象,Flask用這個參數确定程式的根目錄,__name__代表的是這個子產品本身的名稱。
使用route()裝飾器注明通過什麼樣的URL可以通路函數,同時在函數中傳回要顯示在浏覽器中的資訊。代碼如下:
@app.route('/')
def index():
return 'Hello World!'
@app.route('/')這行代碼指定了URL與Python函數的映射關系,我們把處理URL和函數之間關系的程式定義為路由,把被裝飾的函數index()注冊為路由,此處注冊給index()函數的路由為根目錄。
這裡的index()函數叫做視圖函數,視圖函數必須要有傳回值,傳回價值為字元串或簡單的HTML頁面等内容。
系統初始化了,路由和視圖函數有了,Flask程式如何運作呢?Flask程式的運作需要伺服器環境,我們可以通過run方法來啟動Flask自身內建的伺服器。代碼如下:
if __name__=='__main__':
app.run(debug=True)
如果__name__=='__main__',就要啟用Web服務來運作上面的程式,伺服器一旦開啟,就會進入輪詢狀态,等待并處理請求。在app.run()中可以傳入一些參數,比如debug,app.run(debug=Ture),表示設定目前項目為debug模式,也就是調試模式。如果設定了調試模式,遇到程式有錯誤,會在控制台輸出具體的錯誤資訊,否則隻會籠統地報告“應用伺服器錯誤”的資訊。另一方面,如果設定為調試模式,期間又修改了程式代碼,系統會自動重新将修改的代碼送出給Web伺服器,你隻需要確定浏覽器沒有緩存,便可以得到最新修改的代碼結果。
app.run()還可以傳入端口等資訊,比如app.run(host='0.0.0.0',port=8080),host='0.0.0.0'參數設定啟用本機的IP位址可以通路,端口位址指定為8080,如果不指定,則為5000。
接下來,在PyCharm中實作上述項目。
在PyCharm中建立一個名稱為2-1的工程(建立工程注意使用已經存在的“虛拟環境”),如圖2.6所示。
app.py的内容見例2-1。
運作程式,結果如圖2.7所示。
如果啟用的端口不是5000端口,這裡port=8888在筆者的PyCharm 2018.2.1版本中是不會生效的,通路位址仍然為
http://127.0.0.1:5000/,為使新端口位址生效,還需要做進一步設定。
(1)執行Run | Edit Configurations指令,如圖2.8所示。
(2)彈出如圖2.9所示對話框。
(3)在Additional options輸入框中輸入“--host=192.168.31.118 --port=8888”(192.168.31.118為筆者計算機的IPv4位址),當然這裡你也可以輸入“--host=127.0.0.1 --port=8888”。接下來,在浏覽器位址欄可以輸入
http://192.168.31.118:8888/通路網頁,192.168.31.118一個網段内的區域網路計算機也可以通過
通路到此網頁的内容。
2.3 URL傳遞參數
Flask中如果要傳遞一個變量或者一個參數,可以通過表單和位址欄兩種方式來傳遞。其中,通過浏覽器位址欄URL方式傳遞/擷取某個變量或參數使用得比較多。這樣,我們可以使用相同的URL指定不同的參數,來通路不同的内容。
Flask通過URL傳遞參數,傳遞參數的文法是:'/<參數名>/'。需要注意兩點:參數需要放在一對< >(尖括号)内;視圖函數中需要設定同URL中相同的參數名。
下面在PyCharm中建立一名稱為2-2的工程。
02行表示導入Flask子產品;03行表示Flask執行個體化;04行定義路由;05行定義視圖函數;06行是傳回值;07行定義路由;08行表示傳回值;09、10行表示如果某子產品被直接運作,則其__name__為'__main__',條件為真,就開啟調試模式。
?注意:在Python中,所有沒有縮進的代碼都會被執行,__name__是Python的内建函數,指的是目前子產品的名稱,每個子產品都有自己的__name__屬性,但__name__的值是會變化的,如果某子產品被直接運作,則其__name__為'__main__',條件為真,就可以執行app.run()方法,使得整個程式得以運作。當子產品被導入時,代碼不被運作。
如果07行代碼中name沒有指定資料類型,那麼預設就是string資料類型。在浏覽器的位址欄中輸入
http://127.0.0.1:5000/user/zhangsan,回車後便可以得到如圖2.10所示的通路結果。
如果此時在浏覽器位址欄輸入的内容為
http://127.0.0.1:5000/USER/zhangsan,回車後還可以得到如圖2.8所示結果嗎?結果顯然是否定的。因為這裡的user是區分大小寫的。
在if name == '__main__':這行代碼之上繼續增加如下代碼:
@app.route('/news/<int:id>')
def list_news(id):
return "接收到的id為%s" % id
在浏覽器位址欄輸入
http://127.0.0.1:5000/news/1,回車後便可以得到如圖2.11所示結果。
如果在浏覽器的位址欄輸入
http://127.0.0.1:5000/news/1.1,回車後還可以得到正确的結果嗎?結果顯然也是否定的。定義成int資料類型的URL隻能傳遞int類型,定義成float資料類型時,URL隻能傳遞float類型,即定義的是什麼資料類型,URL傳遞的參數就必須為對應的資料類型。
2.4 URL反轉
在2.3節中,我們設定了一些函數通路URL。有時候,在作網頁重定向或是模闆檔案時需要使用在視圖函數中定義的URL,我們必須根據視圖函數名稱得到目前所指向的URL,這就是URL反轉。下面通過一個執行個體來看URL反轉的使用。
下面在PyCharm中建立一名稱為2-3的工程。
使用URL反轉,用到了url_for()函數,需要使用from flask import url_for導入,url_for() 函數最簡單的用法是以視圖函數名作為參數,傳回對應的URL。例如,在上面的程式中如果用url_for('index'),得到的結果是/,運作上述代碼,結果如圖2.12所示。
2.5 頁面跳轉和重定向
使用者在通路某個頁面的時候,我們希望他登入後才能通路該頁面,如果此時他沒有登入,系統就讓浏覽器由目前頁面跳轉到登入頁面,這裡就涉及頁面重定向問題。所謂頁面重定向,就是使用者在打開某個頁面的時候,我們期望頁面跳轉到另一個指定的頁面,讓使用者完成某種操作或執行某個動作。
Flask中提供了重定向函數redirect(),該函數的功能就是跳轉到指定的URL。下面在PyCharm中建立一名稱為2-4的工程。
02行表示當子產品被直接運作時,代碼将被運作,當子產品被導入時,代碼不被執行;03行表示Flask初始化;04行定義路由;05行表示定義視圖函數;06行表示列印輸出;07行表示URL反轉;08行表示網頁重定位;09行表示定義路由;10行表示定位視圖函數;11行表示傳回值;12行表示當子產品被直接運作時,代碼将被運作,當子產品被導入時,代碼不被執行。
重定向是将原本的URL重新定向成為一個新的URL,可以實作頁面的跳轉。Flask中使用到了redirect()函數,需要使用from flask import redirect将其導入才能使用。這裡輸入位址通路的首先應該是index()這個視圖函數,但是index()這個視圖函數直接跳轉到了user_login視圖上,運作結果如圖2.13所示。
2.6 溫 故 知 新
1.學完本章内容後,讀者需要回答:
(1)什麼是Flask?
(2)URL如何傳遞參數?
(3)網頁如何重定向?
2.在下一章中将會學習:
(1)模闆及Flask模闆渲染。
(2)模闆中傳參的方法。
(3)模闆中的條件語句和循環語句的使用。
2.7 習 題
通過下面的習題來檢驗本章的學習情況,習題答案請參考本書配套資源。
【本章習題答案見配套資源源代碼C2習題】
有如下代碼,對其進行URL反轉(從視圖函數到URL的轉換),在index()視圖函數中,請列印輸出my_list()函數的反轉位址。
# encoding utf-8
from flask import Flask,url_for
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
@app.route('/list/')
def my_list():
return 'list'
if __name__ == '__main__':
app.run()