flask訪問404_Flask鉤子函式
技術標籤:flask訪問404
鉤子函式
1.什麼是鉤子函式
在正常執行的程式碼前後,插入一段想要執行的程式碼,這稱為鉤子函式.
2.Flask
中的鉤子函式
上一篇分析了原始碼
flask/app.py
中的Flask()
類,其實它除了實現了應用上下文,請求上下文之外,還實現了一些常用的鉤子hook
函式.常見的鉤子函式有:
鉤子函式 描述 before_first_request
在處理第一個請求前執行,比如連線資料庫操作 before_request
在每次執行請求前執行,比如許可權校驗 after_request
在每次請求之後呼叫,前提是沒有異常丟擲 errorhandler
在訪問應用出錯時,根據錯誤碼,做一些定製 context_processor
上下文鉤子,返回一個字典物件,可以在 jinja
模板中使用teardown_request
在響應銷燬時,執行一個函式 teardown_appcontext
不管時候有異常,當應用上下文被移除時,執行的函式.
1.before_first_request
只有在處理第一次請求之前會執行,之後都不會執行.
應用場景:可以載入一些函式,用來對網站進行一些測試,檢查,如果發現異常,則截斷後續的請求,將整個
Flask
應用停止執行.
fromflaskimportFlask
app=Flask(__name__)
app.config.update({
'DEBUG':True,'AUTO_TEMPLATES_RELOAD':True
})
@app.route('/')
defindex():
return'HelloWorld!'
@app.before_first_request
deftest_app():
print('測試伺服器執行')
if__name__=='__main__':
app.run()輸出:
127.0.0.1--"GET/HTTP/1.1"200-
測試伺服器執行
127.0.0.1--"GET/HTTP/1.1"200-
2.before_request
在每個請求之前都會執行的鉤子.
應用場景:共享
session
的鑑權函式,請求黑白名單過濾,根據endpoint
進行請求等.
fromflaskimportBlueprint,request
bp=Blueprint('api',__name__,url_prefix='/api/')
required={
'api_register':['email','username','password']
}
@bp.before_request
defbefore():
ifnotrequest.is_json:
print(request.endpoint)
print(request.json)
return'請使用json風格的引數訪問'
try:
ifrequest.endpointinrequired:
ifrequest.method=='POST':
missparam_list=[xforxinrequired[request.endpoint]ifxnotinrequest.json.keys()]
iflen(missparam_list)>0:
return'缺少引數'
exceptExceptionase:
print(e)
return"{}???".format(e)
@bp.route('/test/')
deftest():
ifrequest.method=='POST':
return'test'
@bp.route('/api_register/')
defregister():
return'hello'比如在驗證
session
,來檢視使用者是否已經登入
fromflaskimportFlask,session,g
frommodel.apiimportbp
fromosimporturandom
app=Flask(__name__)
app.config.update({
'DEBUG':True,
'AUTO_TEMPLATES_RELOAD':True,
'SECRET_KEY':urandom(24)
})
@app.route('/')
defindex():
session['name']='Python'
return'HelloWorld!'
@app.before_first_request
deftest_app():
print('測試伺服器執行')
app.register_blueprint(bp)
@app.before_request
defbefore():
name=session.get('name')
ifname:
g.name=name
@app.route('/first/')
deffirst():
ifg.name:
return'已登入'
else:
return'請登入'
if__name__=='__main__':
app.run()
3.after_request
請求完成時執行,但是必須傳入一個引數來接受響應物件,並在最後的
return
這個引數,也就是響應內容.場景:一般用於格式化響應結果,包括響應請求頭,響應的格式等.
fromflaskimportFlask,session,g
frommodel.apiimportbp
fromosimporturandom
app=Flask(__name__)
app.config.update({
'DEBUG':True,
'AUTO_TEMPLATES_RELOAD':True,
'SECRET_KEY':urandom(24)
})
@app.route('/')
defindex():
session['name']='Python'
return'HelloWorld!'
@app.before_first_request
deftest_app():
print('測試伺服器執行')
app.register_blueprint(bp)
@app.before_request
defbefore():
name=session.get('name')
ifname:
g.name=name
@app.route('/first/')
deffirst():
ifg.name:
return'已登入'
else:
return'請登入'
@app.after_request
defafter(response):
response.headers['test']='test'
returnresponse
if__name__=='__main__':
app.run()訪問
127.0.0.1/first/
,檢視響應頭.
4.errorhandler
當訪問出錯時,根據錯誤響應碼,進行一些定製化的操作,比如返回
404
頁面.場景: 定製化錯誤資訊,
404
,500
等.
@app.errorhandler
defpage_not_fond(error):
returnrender_template('404.html'),404訪問不存在的頁面時,它會返回定義的
404.html
❯curlhttp://127.0.0.1:5000/sdf
HTMLPUBLIC"-//W3C//DTDHTML3.2Final//EN">
404NotFound
NotFound
TherequestedURLwasnotfoundontheserver.IfyouenteredtheURLmanuallypleasecheckyourspellingandtryagain.
也可以在函式中手動丟擲錯誤,這需要使用到
abort()
函式
fromflaskimportabort
@app.route('/app/')
defmy_app()
#手動彈出一個錯誤abort(404)return'test'訪問同樣會訪問到
404.html
❯curlhttp://127.0.0.1:5000/app/
HTMLPUBLIC"-//W3C//DTDHTML3.2Final//EN">
404NotFound
NotFound
TherequestedURLwasnotfoundontheserver.IfyouenteredtheURLmanuallypleasecheckyourspellingandtryagain.
5.context_processor
將一些資料按照字典的格式返回,可以在
jinja
模板中使用.這樣就不用在每個檢視函式中都去返回一次render_template('xxx.html',info=xxx)
需要注意的是,這個函式必須返回一個字典物件,不管最後的判斷函式是怎麼樣的.
場景:適用多個頁面返回一個同樣的值.比如登入後,在每個頁面的標頭都會顯示使用者的使用者名稱.
#app.py
@app.context_processor
defcontext():
#表示登入
ifg.name:
return{'username':'Jack'}
else:
return{}
@app.route('/test1/')
deftest1():
returnrender_template('test1.html')
@app.route('/test2/')
deftest2():
returnrender_template('test2.html')在
test1.html\test2.html
中接受username
{# test1.html, test2.html# }
{{ username}}
6.teardown_request
在響應銷燬時,執行一個繫結的函式.
after_requtst
:每一個請求之後繫結一個函式,如果請求沒有異常teardown_request
:每一個請求之後繫結一個函式,即是有異常場景:銷燬資料庫
db
連線
@app.teardown_request
defteardown():
db=getattr(g,'database',None)
ifdbisnotNone:
db.close()
7.teardown_appcontext
- END -不管是否有異常,當
app
的上下文被移除之後執行的函式,可以進行資料庫的提交或者回滾.
@app.teardown_appcontext
defteardown(cmd=None):
ifcmdisNone:
db.session.commit()
else:
db.session.rollback()
db.session.remove()