werkzeugs 是 flask 的底層wsgi庫。
def dispath_request(self, request):
return response('hello world!')
request = request(environ)
response = self.dispath_request(request)
return response(environ, start_response)
environ:包含全部的http請求資訊的字典,由wsgi server
解包 http 請求生成。
start_response:乙個wsgi server
提供的函式,呼叫可以返回相應的狀態嗎和http報文頭,函式在返回前必須呼叫一次。
flask有兩種context(上下文),分別是
在 'flask/globals.py' **中:
# context locals
_request_ctx_stack = localstack()
# localstack 是由werkzeug提供的棧結構類提供了push、pop等方法
# 並且local物件是werkzeug開發的類似 thinking.local(用於隔離不同執行緒間的全域性變數) 物件,實現了在同乙個協程中資料的隔離和全域性性,具體怎麼實現看源**,暫時沒看明白
# partial(_lookup_req_object, 'request') 總是返回 localstack 棧頂物件的 request 屬性
# localproxy 用於**local物件和localstack物件,至於為什麼使用**。。
request = localproxy(partial(_lookup_req_object, 'request'))
session = localproxy(partial(_lookup_req_object, 'session'))
flask local
為什麼要使用 localproxy 而不直接使用 local 和 localstack #
### 在 `flask/ctx.py` **中
# # but there a basic "refcount" is enough to track them.
self._refcnt = 0
self._refcnt += 1
if hasattr(sys, 'exc_clear'):
sys.exc_clear()
## 在 flask/cli.py 中有
# @click.pass_context
def decorator(__ctx, *args, **kwargs): # decorator 被裝飾器後 _ctx 引數是 threading 的 local() 物件
return __ctx.invoke(f, *args, **kwargs)
# requestcontext 請求上下文##
def request_context(self, environ): # 一次請求的環境變數
return requestcontext(self, environ)
## 在flask/ctx.py下:
#class requestcontext(object):
if request is none:
self.request = request
self.flashes = none
self.session = none
......
def push(self):
..._request_ctx_stack.push(self) ##
ctx = self.request_context(environ)
error = none
try:
try:
ctx.push()
response = self.full_dispatch_request()
except exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = none
ctx.auto_pop(error)
原始碼中有這麼幾個裝飾器:
# url_defaults(self, f) 和 url_value_preprocessor(self, f) 的使用
from flask import blueprint, render_template
profile = blueprint('profile', __name__, url_prefix='/')
@profile.url_defaults
def add_user_url_slug(endpoint, values):
values.setdefault('user_url_slug', g.user_url_slug)
@profile.url_value_preprocessor
def pull_user_url_slug(endpoint, values):
g.user_url_slug = values.pop('user_url_slug')
query = user.query.filter_by(url_slug=g.user_url_slug)
g.profile_owner = query.first_or_404()
@profile.route('/')
def timeline():
return render_template('profile/timeline.html')
@profile.route('/photos')
def photos():
return render_template('profile/photos.html')
@profile.route('/about')
def about():
return render_template('profile/about.html')
方法:click 包 把python**打包成命令列工具
mimetypes 包 檢視檔案型別
itsdangerous 簽名 序列化字串
Flask之請求上下文 應用上下文的概述
flask中有兩種上下文,請求上下文和應用上下文 一 請求上下文 request context request和session都屬於請求上下文物件。2.g 處理請求時,用於臨時儲存的物件,每次請求都會重設這個變數。比如 我們可以獲取一些臨時請求的使用者資訊。request 在每次http請求發生時...
Flask 中請求上下文和應用上下文的區別和作用?
兩者作用 請求上下文 request context flask從客戶端收到請求時,要讓檢視函式能訪問一些物件,這樣才能處理請求。請求物件是一 個很好的例子,它封裝了客戶端傳送的http 請求。要想讓檢視函式能夠訪問請求物件,乙個顯而易見的方式是將其作為引數傳入檢視函式,不過 這會導致程式中的每個檢...
二十 用上下文管理應用
使用react可以很容易通過react元件跟蹤資料流。當你看到乙個元件,你就可以看到哪些props正在傳遞,這使得你的應用很容易知道在做什麼。在某些情況下,你希望通過元件樹傳遞資料,而不是在每個級別的中元件手動傳遞props,你可以直接在react中使用強大的 context 來做到這一點。絕大多數...