2.1 初始化:所有Flasky程序都要創建一個程序實例,web服務器使用web服務器網關接口把接受自客戶端的所有請求都轉交給這個Flasky類對象處理。
from flask import Flasky
app = Flask(_name_)
在python中,_name_變量就是所需的值
2.2 路由和視圖函數
瀏覽器發請求到服務器。服務器發請求到Flasky程序實例,程序實例保存URL到python函數的映射關係,即路由。
Flasky定義路由,使用程序實例提供的app.route修飾器把函數註冊爲路由:
@app.route(‘/’)
def index();
return ‘<h1>Hello World!</h1>’
例子即index()函數註冊爲程序根地址的處理程序。當訪問部署的地址時,函數返回值即爲響應,函數即爲視圖函數。
@app.route(‘/user/<name>’)
def user(name):
return ‘<h1>Hello,%s!</h1>’ % name
尖括號爲動態部分,默認字符串,支持<int:id>還有float和path,Flasky將動態部分作爲參數傳入函數。
2.3 啓動服務器
run方法啓動Flasky集成的開發web服務器
if _name_ == ‘_main_’:
app.run(debug=True)
這裏_name_ == ‘_main_’是確保直接執行這個腳本才啓動開發web服務器;debug=True啓用調試模式。
2.4
2.4.1 一個完整的程序
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
if __name__=='__main__':
app.run(debug=True)
使用python解釋器解釋
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
瀏覽器打開http://127.0.0.1:5000/即可Hello World!
2.4.2 另一個完整的包含動態路由的程序
#coding=utf8
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)
使用python解釋器解釋
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
瀏覽器打開http://127.0.0.1:5000/爲根目錄,顯示Hello World!;瀏覽器打開http://127.0.0.1:5000/user/Jorson爲子目錄,顯示Hello,Jorson!
2.5.1 請求-響應循環
2.5.1.1 請求上下文(request\session)
Flask從客戶端收到請求,讓視圖函數訪問請求對象。爲了避免大量的可有可無的參數,使用上下文臨時把對象變爲全局可訪問。
from flask import request
@app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return '<p>Your browser is %s</p>' % user_agent
這裏把request當全局變量,但實際上不可能是全局變量。Flask讓特定變量在一個線程中全局可訪問。
2.5.1.2 程序上下文(current_app\g)
Flask在分發請求之前激活程序和請求上下文,處理完成再刪除。調用app.app_context()可獲得一個程序的上下文。
2.5.2 請求調度
URL映射是URL和視圖函數之間的對應關係。Flask使用app.route修飾器或者非修飾器形式的app.add_url_rule()生成映射。
查看hello.py生成的映射:
(venv) C:\Windows\System32\flasky>python
>>> from hello import app
>>> app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])
其中,/和/user/<name>使用app.route修飾器定義,/static/<filename>路由是特殊路由用於訪問靜態文件。每個路由都有HEAD,Options,GET請求方法,對應不同的視圖函數。HEAD和OPTIONS方法由Flask自動處理,因此以上的程序中,URL映射的三個路由都使用GET方法。
2.5.3 請求鉤子
Flask提供註冊通用函數的功能,可在請求前後調用,請求鉤子使用修飾器實現:
before_first_request:註冊一個函數,在處理第一個請求之前運行
before_request:註冊一個函數,在每次請求之前運行
after_request:註冊一個函數,如果沒有未處理的異常拋出,在每次請求之後運行
teardown_request:註冊一個函數,即使有未處理的異常拋出,也在每次請求之後運行
請求鉤子函數和視圖函數之間共享數據一般使用上下文全局變量g,例如before_request處理程序可以從數據庫加載已登陸用戶,保存在g.user中,隨後調用視圖函數再使用g.user獲取用戶。
2.5.4 響應
2.5.4.1 返回元組
HTTP響應的很重要的部分是狀態碼,Flask默認爲200表明請求已成功處理。若使用其他數字代碼則可以作爲第二個返回值
@app.route('/')
def index():
return '<h1>Bad</h1>',400
2.5.4.2 返回對象
除了返回1,2,3個值組成的元組, Flask還可以返回Request對象。make_response()函數接受1,2或3個參數,並返回Response對象。
from flask import make_response
@app.route('/')
def index():
response = make_response('<h1>This document carries a cookie!</h1>')
response.set_cookie('answer','42')
return response
2.5.4.3 重定向
特殊響應類型,無頁面文檔,只告訴瀏覽器一個新地址用於加載新頁面。常用於web表單。重定向常使用302狀態碼,指向地址由location首部提供。重定向響應可以使用3個值形式的返回值生成,也可以在Response對象中設定,也用於redirect()輔助函數:
from flask import redirect
@app.route('/')
def index():
return redirect('http://www.example.com')
2.5.4.4 處理錯誤的響應
abort函數生成。
from flask import abort
@app.route('/user/<id>')
def get_user(id):
user = load_user(id)
if not user:
abort(404)
return '<h1>Hello,%s</h1>' % user.name
注意:abort直接拋出異常
2.6 Flask擴展
Flask支持大量擴展,包括Python標準包和代碼庫。
2.6.1 Flask-Script支持命令行選項
Flask的開發web服務器支持很多啓動選項,在腳本中作爲參數傳給app.run()不方便,可以使用命令行參數。
Flask-Script是一個Flask擴展,爲Flask程序添加了一個命令行解析器,自帶一組常用選項,支持自定義命令。
安裝Flask-Script:pip install flask-script
from flask import Flask
from flask_script import Manager
app = Flask(__name__)
manager = Manager(app)
@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__':
manager.run()
運行代碼可以使用一組基本命令行選項
shell:在程序上下文中啓動Python shell會話,進行運行維護任務或測試、調試
runserver:啓動web服務器,調試模式
--host:參數,告訴web服務器在哪個網路接口上監聽來自客戶端的連接,默認監聽本地連接,使用下述命令來監聽公共網絡接口的連接:
python hello.py runserver --host 0.0.0.0