先看一個流程圖:
1、當一個請求進入的時候,Flask框架首先會實例化一個Request Context,封裝了請求信息,保存在Request中。生成請求上下文后,Flask框架會將請求上下文推入到_request_ctx_stack棧中。調用的就是Request Context上下文的push方法
2、App Context 是如何入棧的呢?
Request Context在入棧之前,會先去app_ctx_stack棧頂檢查下,棧頂元素是否存在,如果棧頂元素為空或者不是當前對象,那么Flask會把App Context推入到app_ctx_stack棧中,然后才會把Request Context推入到request_ctx_stack中。
3、request和current_app,這兩者用於都是指向各自棧的棧頂的,也就是說使用current_app和request的時候,都是在間接的操作_app_ctx_stack和_request_ctx_context棧頂元素。
如果棧頂元素時空的,Local Proxy將會出現unbound,這時候使用他們就會報出 working outside application context的錯誤,這個錯誤在Flask中,經常不小心就會遇到。
所以出現這個錯誤的解決方案就是:當我們要使用current_app的時候,如果棧頂元素為空,那我們手動的將app context推入棧中,就不會出現這種情況了。
一般流程是:
ctx = app.get_context():獲得APPContext應用上下文對象,
然后調用 ctx.push() 方法就可以將其推入到棧中
在使用完畢后,還需要調用ctx.pop() 將其從棧中彈出。
上面的代碼 可以 結合 with 語句 改寫成上下文管理的方式
with app.app_context():
pass
【棧:后進先出 隊列:先進先出】