Flask是一個Python實現的Web開發框架, Flask的設計思想為核心盡可能的微小和專能,擴展功能則由獨立模塊靈活實現.
Flask應用基於jinja2模板引擎和werkzeug WSGI工具集, 若有需要可以閱讀它們的文檔.
可以使用pip安裝flask;
pip install flask
Hello World
首先來讓服務器打個招呼:
from flask import Flask
app = Flask('hello')
@app.route('/hello/')
def hello():
return 'Hello World!'
app.run(port=8080, debug=True)
運行這段腳本, 訪問localhost:8080/hello/
則可以看到來自服務器的Hello World信息.
@app.route('/hello/')
修飾器用於綁定url和處理函數, 可以將多個url綁定到一個函數上:
@app.route('/hello/')
@app.route('/')
def hello():
return 'Hello World!'
Flask建議使用像/hello/
這樣兩邊含有斜線的url, 這樣當訪問/hello
時會自動重定向到/hello/
.
而@app.route('/hello')
不會對/hello/
請求進行響應.
app.run(port=8080, debug=True)
用於啟動app, port指定監聽的端口.
app的參數還可以直接設置:
app.port = 8080
app.run()
debug模式下, 當腳本改變時服務器會自動重啟.在需要fork的環境下debug模式無法使用, 即不能用於生產環境下.
編寫響應函數
響應函數的返回值將生成response返回給客戶端, 上文已經展示用str作為響應.
使用模板
Flask使用jinja2模板引擎, 可以使用模板作為響應:
from flask import render_template
@app.route('/template/')
def show_template():
return render_template('template.html', name='finley')
默認模板文件存放在工作目錄的templates
子目錄下.
使用符合jinja2規則的模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Template</title>
</head>
<body>
{{ name }}
</body>
</html>
視圖函數的返回值會被自動轉換為一個響應對象,Flask 把返回值轉換為響應對象的規則為:
-
合法的響應對象會被直接返回.
-
若返回的是一個字符串,響應對象會用字符串數據和默認參數創建。
-
若返回的是一個元組,則必須是 (response, status, headers) 的形式,且至少包含一個元素. status 值會覆蓋狀態代碼, headers 可以是一個列表或字典,作為額外的消息標頭值.
-
若上述條件均不滿足, Flask 會假設返回值是一個合法的 WSGI 應用程序,並轉換為一個請求對象.
使用靜態文件
靜態文件存放在static
子目錄下, 使用'/static'+文件名進行訪問, 或者使用url_for
來獲得靜態文件url:
url_for('static', filename='jquery.js')
進行重定向
使用redirect可以將請求重定向到指定url:
from flask import redirect, url_for
@app.route('/index/')
def index():
return redirect(url_for('static', filename='index.html'))
redirect(url, code=302)
默認使用302(臨時重定向)作為狀態碼, 也支持其它3開頭的狀態碼: 303, 305, 307.
獲得請求參數
獲得url匹配
@app.route()
可以將url中匹配的字符串當做位置參數傳入響應函數:
@app.route('/user/<username>/')
def user_info(username):
return 'hello, %s' % username
若訪問/user/finley/
, 響應函數user_info
會得到值為'finley'的位置參數.
獲得query參數
其它包含在HTTP請求中的參數我們需要導入request對象:
from flask import request
在全局request對象中獲得query參數:
@app.route('/query/')
def query():
return request.args.get('query')
獲得表單與頭部參數
在request.form中獲得表單提交的參數:
@app.route('/do-login/', methods=['POST'])
def do_login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
return '%s , login success' % username
else:
return 'Please use POST method'
@app.route
的methodes參數指定了允許的HTTP方法, 默認僅允許'GET'.
我們可以在request.headers中獲得包含在頭部的參數:
request.headers['ACCEPT_LANGUAGE']
當然也可以添加或修改headers.
注意上述語句獲得的頭部參數實際是'HTTP_ACCEPT_LANGUAGE'.
文件上傳
app.config是一個可以自定義配置的字典, 我們在里面寫入上傳文件的保存目錄:
app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__), "upload")
編寫上傳文件的表單記得設置enctype="multipart/form-data"
:
<form action="/do-upload/" method="post" enctype="multipart/form-data">
<input type="file" name="filename">
<input type="submit" value="submit">
</form>
從request.files
中獲得文件信息, 並使用save方法保存:
from werkzeug.utils import secure_filename
@app.route('/do-upload/', methods=['POST'])
def do_upload():
if request.method == 'POST':
f = request.files['filename']
f.save(os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(f.filename)))
return 'upload success'
else:
return 'Please use POST method'
secure_filename
方法可以處理文件名中的非法字符和轉義字符返回合法文件名.
session與cookie
cookie
使用request可以很方便地獲得cookie:
token = request.cookies.get('token')
上文中的響應函數返回值均被Flask轉換為response對象, 然而cookie需要設置在response對象上所以我們需要自行建立響應對象:
from flask import make_response
@app.route('/auth/<redirect_uri>')
def auth(redirect_uri):
response = make_response(redirect(redirect_uri))
uid = request.cookies.get('uid')
token = authen(uid)
response.set_cookie('token', token)
return response
session
與cookie將數據保存在客戶端不同, session將數據保存在服務端並使用加密的cookie識別客戶端身份.
若要使用session首先要為app設置secret_key
用來簽名:
app.secret_key = 'thisGGisRRa12secret'
session的是一個保存了相關參數的字典, 可以方便的進行操作:
session['last_login'] = time()
last_login = session['last_login']
session.pop('last_login')
參考資料: