轉載請在文章開頭附上原文連接地址:http://www.javashuo.com/article/p-vakmmhen-ks.htmlhtml
在客戶端和服務器交互的過程當中,有些準備工做或掃尾工做須要處理,好比:python
爲了讓每一個視圖函數避免編寫重複功能的代碼,Flask提供了通用設置的功能,即請求鉤子。數據庫
請求鉤子是經過裝飾器的形式實現,Flask支持以下四種請求鉤子:json
代碼flask
config.pybash
class Config(object): DEBUG = True SECRET_KEY = "abcccddgadsag"
hook.py服務器
from flask import Flask from config import Config app = Flask(__name__) app.config.from_object(Config) @app.before_first_request def before_firest_request(): print("----- before_first_requets-----") print("系統初始化的時候,執行這個鉤子方法") print("會在接收到第一個用戶請求時,執行這裏的代碼") @app.before_request def before_request(): print("----before request") print("每一次接收到用戶請求時,執行這個鉤子方法") print("通常能夠用來判斷權限,或者轉換路由參數或者預處理客戶端的請求的數據") @app.after_request def after_request(response): print("----after_request----") print("在處理請求之後,執行這個鉤子方法") print("通常能夠用於記錄會員/管理員的操做歷史,瀏覽歷史,清理收尾的工做") response.headers["Content-Type"] = "application/json" return response @app.teardown_request def teardown_request(exc): print("----teardown_request----") print("在每一次請求之後,執行這個鉤子方法,若是有異常錯誤,則會傳遞錯誤異常對象到當前方法的參數中") print(exc) @app.route("/hook") def hook(): print("----這是視圖函數----") print("視圖函數被運行了") return "這是視圖函數" if __name__ == '__main__': app.run(host="127.0.0.1", port=80)
----- before_first_requets----- 系統初始化的時候,執行這個鉤子方法 會在接收到第一個用戶請求時,執行這裏的代碼 ----before request 每一次接收到用戶請求時,執行這個鉤子方法 通常能夠用來判斷權限,或者轉換路由參數或者預處理客戶端的請求的數據 ----這是視圖函數---- 視圖函數被運行了 ----after_request---- 在處理請求之後,執行這個鉤子方法 通常能夠用於記錄會員/管理員的操做歷史,瀏覽歷史,清理收尾的工做 ----teardown_request---- 在每一次請求之後,執行這個鉤子方法,若是有異常錯誤,則會傳遞錯誤異常對象到當前方法的參數中 None
# abort(404) abort(500)
拋出狀態碼的話,只能拋出 HTTP 協議的錯誤狀態碼cookie
@app.errorhandler(500) def internal_server_error(e): return '服務器搬家了'
@app.errorhandler(ZeroDivisionError) def zero_division_error(e): return '除數不能爲0'
上下文:即語境,語意,在程序中能夠理解爲在代碼執行到某一時刻時,根據以前代碼所作的操做以及下文即將要執行的邏輯,能夠決定在當前時刻下能夠使用到的變量,或者能夠完成的事情。session
Flask中有兩種上下文,請求上下文(request context)和應用上下文(application context)。app
Flask中上下文對象:至關於一個容器,保存了 Flask 程序運行過程當中的一些信息。
app = Flask(__name__)
建立的這個對象app
;http
請求發生時,WSGI server
(好比gunicorn)調用Flask.__call__()
以後,在Flask
對象內部建立的Request
對象;思考:在視圖函數中,如何取到當前請求的相關數據?好比:請求地址,請求方式,cookie等等
在 flask 中,能夠直接在視圖函數中使用 request 這個對象進行獲取相關數據,而 request 就是請求上下文的對象,保存了當前本次請求的相關數據,請求上下文對象有:request、session
它的字面意思是 應用上下文,但它不是一直存在的,它只是request context 中的一個對 app 的代理(人),所謂local proxy。它的做用主要是幫助 request 獲取當前的應用,它是伴 request 而生,隨 request 而滅的。
應用上下文對象有:current_app,g
應用程序上下文,用於存儲應用程序中的變量,能夠經過current_app.name打印當前app的名稱,也能夠在current_app中存儲一些變量,例如:
current_app.name current_app.test_value='value'
g 做爲 flask 程序全局的一個臨時變量,充當者中間媒介的做用,咱們能夠經過它傳遞一些數據,g 保存的是當前請求的全局變量,不一樣的請求會有不一樣的全局變量,經過不一樣的thread id區別
g.name='abc'
注意:不一樣的請求,會有不一樣的全局變量
from flask import Flask # 新增一個配置文件,在配置文件中設置配置信息 from config import Config from flask import request app = Flask(__name__) app.config.from_object(Config) """請求上下文""" class Model(object): def __init__(self): print("模型接受到數據,num=%s" % request.args.get("username") ) @app.route("/context") def context(): Model() return "ok" @app.route("/context2") def context2(): Model() return "ok" """應用上下文""" from flask import current_app @app.route('/context3') def context3(): # current_app 只是app對象在視圖被請求時的一個代理對象[別名對象] print( current_app.username ) # 咱們能夠直接調用app對象所擁有的屬性和方法 return "應用上下文" from flask import g class Model2(object): def __init__(self): print("模型接受到數據,num=%s" % g.username ) @app.route('/context4') def context4(): # g是一個臨時的全局對象,只會在本次請求中獲取到數據 g.username = request.args.get("username") Model2() return "應用上下文" if __name__ == '__main__': # app 系統應用對象 app.username='應用上下文的username' print('----運行項目以前----') app.run()
安裝命令:
pip install flask-script
集成 Flask-Script到flask應用中
from flask import Flask app = Flask(__name__) """使用flask_script啓動項目""" from flask_script import Manager manage = Manager(app) @app.route('/') def index(): return 'hello world' if __name__ == "__main__": manager.run()
Flask-Script 還能夠爲當前應用程序添加腳本命令
"""自定義flask_script終端命令""" from flask_script import Command class HelloCommand(Command): """命令的相關描述""" def run(self): with open("text.txt","w") as f: f.write("hello\r\nhello") pass print("這是執行了hello命令") manage.add_command('hello', HelloCommand() )