九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
快速入門(mén)

迫不及待要開(kāi)始了嗎?本頁(yè)提供了一個(gè)很好的 Flask 介紹,并假定你已經(jīng)安裝好了 Flask。如果沒(méi)有,請(qǐng)?zhí)D(zhuǎn)到 安裝 章節(jié)。

一個(gè)最小的應(yīng)用?

一個(gè)最小的 Flask 應(yīng)用看起來(lái)會(huì)是這樣:

from flask import Flaskapp = Flask(__name__)@app.route('/')def hello_world():    return 'Hello World!'if __name__ == '__main__':    app.run()

把它保存為 hello.py (或是類似的),然后用 Python 解釋器來(lái)運(yùn)行。確保你的應(yīng)用文件名不是 flask.py ,因?yàn)檫@將與 Flask 本身沖突。

$ python hello.py * Running on http://127.0.0.1:5000/

現(xiàn)在訪問(wèn) http://127.0.0.1:5000/ ,你會(huì)看見(jiàn) Hello World 問(wèn)候。

那么,這段代碼做了什么?

  1. 首先,我們導(dǎo)入了 Flask 類。這個(gè)類的實(shí)例將會(huì)是我們的 WSGI 應(yīng)用程序。
  2. 接下來(lái),我們創(chuàng)建一個(gè)該類的實(shí)例,第一個(gè)參數(shù)是應(yīng)用模塊或者包的名稱。如果你使用單一的模塊(如本例),你應(yīng)該使用 __name__ ,因?yàn)槟K的名稱將會(huì)因其作為單獨(dú)應(yīng)用啟動(dòng)還是作為模塊導(dǎo)入而有不同(也即是 '__main__' 或?qū)嶋H的導(dǎo)入名)。這是必須的,這樣 Flask才知道到哪去找模板、靜態(tài)文件等等。詳情見(jiàn) Flask的文檔。
  3. 然后,我們使用 route() 裝飾器告訴 Flask 什么樣的URL 能觸發(fā)我們的函數(shù)。
  4. 這個(gè)函數(shù)的名字也在生成 URL 時(shí)被特定的函數(shù)采用,這個(gè)函數(shù)返回我們想要顯示在用戶瀏覽器中的信息。
  5. 最后我們run() 函數(shù)來(lái)讓?xiě)?yīng)用運(yùn)行在本地服務(wù)器上。其中 if __name__ == '__main__': 確保服務(wù)器只會(huì)在該腳本被Python 解釋器直接執(zhí)行的時(shí)候才會(huì)運(yùn)行,而不是作為模塊導(dǎo)入的時(shí)候。

欲關(guān)閉服務(wù)器,按 Ctrl+C。

外部可訪問(wèn)的服務(wù)器

如果你運(yùn)行了這個(gè)服務(wù)器,你會(huì)發(fā)現(xiàn)它只能從你自己的計(jì)算機(jī)上訪問(wèn),網(wǎng)絡(luò)中其它任何的地方都不能訪問(wèn)。在調(diào)試模式下,用戶可以在你的計(jì)算機(jī)上執(zhí)行任意 Python 代碼。因此,這個(gè)行為是默認(rèn)的。

如果你禁用了 debug 或信任你所在網(wǎng)絡(luò)的用戶,你可以簡(jiǎn)單修改調(diào)用run() 的方法使你的服務(wù)器公開(kāi)可用,如下:

app.run(host='0.0.0.0')

這會(huì)讓操作系統(tǒng)監(jiān)聽(tīng)所有公網(wǎng) IP。

調(diào)試模式?

雖然 run() 方法適用于啟動(dòng)本地的開(kāi)發(fā)服務(wù)器,但是你每次修改代碼后都要手動(dòng)重啟它。這樣并不夠優(yōu)雅,而且 Flask 可以做到更好。如果你啟用了調(diào)試支持,服務(wù)器會(huì)在代碼修改后自動(dòng)重新載入,并在發(fā)生錯(cuò)誤時(shí)提供一個(gè)相當(dāng)有用的調(diào)試器。

有兩種途徑來(lái)啟用調(diào)試模式。一種是直接在應(yīng)用對(duì)象上設(shè)置:

app.debug = Trueapp.run()

另一種是作為 run 方法的一個(gè)參數(shù)傳入:

app.run(debug=True)

兩種方法的效果完全相同。

注意

盡管交互式調(diào)試器在允許 fork 的環(huán)境中無(wú)法正常使用(也即在生產(chǎn)服務(wù)器上正常使用幾乎是不可能的),但它依然允許執(zhí)行任意代碼。這使它成為一個(gè)巨大的安全隱患,因此它 絕對(duì)不能用于生產(chǎn)環(huán)境 。

運(yùn)行中的調(diào)試器截圖:

想用其它的調(diào)試器? 參見(jiàn) 調(diào)試器操作 。

路由?

現(xiàn)代 Web 應(yīng)用的 URL 十分優(yōu)雅,易于人們辨識(shí)記憶,這一點(diǎn)對(duì)于那些面向使用低速網(wǎng)絡(luò)連接移動(dòng)設(shè)備訪問(wèn)的應(yīng)用特別有用。如果可以不訪問(wèn)索引頁(yè),而是直接訪問(wèn)想要的那個(gè)頁(yè)面,他們多半會(huì)笑逐顏開(kāi)而再度光顧。

如上所見(jiàn), route() 裝飾器把一個(gè)函數(shù)綁定到對(duì)應(yīng)的URL 上。

這里是一些基本的例子:

@app.route('/')def index():    return 'Index Page'@app.route('/hello')def hello():    return 'Hello World'

但是,不僅如此!你可以構(gòu)造含有動(dòng)態(tài)部分的 URL,也可以在一個(gè)函數(shù)上附著多個(gè)規(guī)則。

變量規(guī)則?

要給 URL 添加變量部分,你可以把這些特殊的字段標(biāo)記為 ,這個(gè)部分將會(huì)作為命名參數(shù)傳遞到你的函數(shù)。規(guī)則可以用 指定一個(gè)可選的轉(zhuǎn)換器。這里有一些不錯(cuò)的例子:

@app.route('/user/')def show_user_profile(username):    # show the user profile for that user    return 'User %s' % username@app.route('/post/')def show_post(post_id):    # show the post with the given id, the id is an integer    return 'Post %d' % post_id

轉(zhuǎn)換器有下面幾種:

int接受整數(shù)
floatint ,但是接受浮點(diǎn)數(shù)
path和默認(rèn)的相似,但也接受斜線

唯一 URL / 重定向行為

Flask 的 URL 規(guī)則基于 Werkzeug 的路由模塊。這個(gè)模塊背后的思想是基于 Apache 以及更早的 HTTP 服務(wù)器主張的先例,保證優(yōu)雅且唯一的 URL。

以這兩個(gè)規(guī)則為例:

@app.route('/projects/')def projects():    return 'The project page'@app.route('/about')def about():    return 'The about page'

雖然它們看起來(lái)著實(shí)相似,但它們結(jié)尾斜線的使用在 URL 定義 中不同。第一種情況中,指向 projects 的規(guī)范 URL 尾端有一個(gè)斜線。這種感覺(jué)很像在文件系統(tǒng)中的文件夾。訪問(wèn)一個(gè)結(jié)尾不帶斜線的 URL 會(huì)被Flask 重定向到帶斜線的規(guī)范 URL 去。

然而,第二種情況的 URL 結(jié)尾不帶斜線,類似 UNIX-like 系統(tǒng)下的文件的路徑名。訪問(wèn)結(jié)尾帶斜線的 URL 會(huì)產(chǎn)生一個(gè) 404 “Not Found” 錯(cuò)誤。

這個(gè)行為使得在遺忘尾斜線時(shí),允許關(guān)聯(lián)的 URL 接任工作,與 Apache 和其它的服務(wù)器的行為并無(wú)二異。此外,也保證了 URL 的唯一,有助于避免搜索引擎索引同一個(gè)頁(yè)面兩次。

構(gòu)造 URL?

如果 Flask 能匹配 URL,那么 Flask 可以生成它們嗎?當(dāng)然可以。你可以用url_for() 來(lái)給指定的函數(shù)構(gòu)造 URL。它接受函數(shù)名作為第一個(gè)參數(shù),也接受對(duì)應(yīng) URL 規(guī)則的變量部分的命名參數(shù)。未知變量部分會(huì)添加到URL 末尾作為查詢參數(shù)。這里有一些例子:

>>> from flask import Flask, url_for>>> app = Flask(__name__)>>> @app.route('/')... def index(): pass...>>> @app.route('/login')... def login(): pass...>>> @app.route('/user/')... def profile(username): pass...>>> with app.test_request_context():...  print url_for('index')...  print url_for('login')...  print url_for('login', next='/')...  print url_for('profile', username='John Doe')...//login/login?next=//user/John Doe

(這里也用到了 test_request_context() 方法,下面會(huì)解釋。即使我們正在通過(guò) Python 的 shell 進(jìn)行交互,它依然會(huì)告訴 Flask 要表現(xiàn)為正在處理一個(gè)請(qǐng)求。請(qǐng)看下面的解釋。 環(huán)境局部變量

為什么你要構(gòu)建 URL 而非在模板中硬編碼?這里有三個(gè)絕妙的理由:

  1. 反向構(gòu)建通常比硬編碼的描述性更好。更重要的是,它允許你一次性修改 URL,而不是到處邊找邊改。
  2. URL 構(gòu)建會(huì)轉(zhuǎn)義特殊字符和 Unicode 數(shù)據(jù),免去你很多麻煩。
  3. 如果你的應(yīng)用不位于 URL 的根路徑(比如,在 /myapplication 下,而不是 / ), url_for() 會(huì)妥善處理這個(gè)問(wèn)題。

HTTP 方法?

HTTP (與 Web 應(yīng)用會(huì)話的協(xié)議)有許多不同的訪問(wèn) URL 方法。默認(rèn)情況下,路由只回應(yīng) GET 請(qǐng)求,但是通過(guò) route() 裝飾器傳遞methods 參數(shù)可以改變這個(gè)行為。這里有一些例子:

@app.route('/login', methods=['GET', 'POST'])def login():    if request.method == 'POST':        do_the_login()    else:        show_the_login_form()

如果存在 GET ,那么也會(huì)替你自動(dòng)地添加 HEAD,無(wú)需干預(yù)。它會(huì)確保遵照 HTTP RFC (描述 HTTP 協(xié)議的文檔)處理 HEAD 請(qǐng)求,所以你可以完全忽略這部分的 HTTP 規(guī)范。同樣,自從 Flask 0.6 起, 也實(shí)現(xiàn)了OPTIONS 的自動(dòng)處理。

你不知道一個(gè) HTTP 方法是什么?不必?fù)?dān)心,這里會(huì)簡(jiǎn)要介紹 HTTP 方法和它們?yōu)槭裁粗匾?/p>

HTTP 方法(也經(jīng)常被叫做“謂詞”)告知服務(wù)器,客戶端想對(duì)請(qǐng)求的頁(yè)面 些什么。下面的都是非常常見(jiàn)的方法:

GET
瀏覽器告知服務(wù)器:只 獲取 頁(yè)面上的信息并發(fā)給我。這是最常用的方法。
HEAD
瀏覽器告訴服務(wù)器:欲獲取信息,但是只關(guān)心 消息頭 。應(yīng)用應(yīng)像處理GET 請(qǐng)求一樣來(lái)處理它,但是不分發(fā)實(shí)際內(nèi)容。在 Flask 中你完全無(wú)需人工 干預(yù),底層的 Werkzeug 庫(kù)已經(jīng)替你打點(diǎn)好了。
POST
瀏覽器告訴服務(wù)器:想在 URL 上 發(fā)布 新信息。并且,服務(wù)器必須確保數(shù)據(jù)已存儲(chǔ)且僅存儲(chǔ)一次。這是 HTML 表單通常發(fā)送數(shù)據(jù)到服務(wù)器的方法。
PUT
類似 POST 但是服務(wù)器可能觸發(fā)了存儲(chǔ)過(guò)程多次,多次覆蓋掉舊值。你可能會(huì)問(wèn)這有什么用,當(dāng)然這是有原因的。考慮到傳輸中連接可能會(huì)丟失,在這種 情況下瀏覽器和服務(wù)器之間的系統(tǒng)可能安全地第二次接收請(qǐng)求,而不破壞其它東西。因?yàn)?POST 它只觸發(fā)一次,所以用 POST 是不可能的。
DELETE
刪除給定位置的信息。
OPTIONS
給客戶端提供一個(gè)敏捷的途徑來(lái)弄清這個(gè) URL 支持哪些 HTTP 方法。從 Flask 0.6 開(kāi)始,實(shí)現(xiàn)了自動(dòng)處理。

有趣的是,在 HTML4 和 XHTML1 中,表單只能以 GETPOST 方法提交到服務(wù)器。但是 JavaScript 和未來(lái)的 HTML 標(biāo)準(zhǔn)允許你使用其它所有的方法。此外,HTTP 最近變得相當(dāng)流行,瀏覽器不再是唯一的 HTTP 客戶端。比如,許多版本控制系統(tǒng)就在使用 HTTP。

靜態(tài)文件?

動(dòng)態(tài) web 應(yīng)用也會(huì)需要靜態(tài)文件,通常是 CSS 和 JavaScript 文件。理想狀況下,你已經(jīng)配置好 Web 服務(wù)器來(lái)提供靜態(tài)文件,但是在開(kāi)發(fā)中,F(xiàn)lask 也可以做到。只要在你的包中或是模塊的所在目錄中創(chuàng)建一個(gè)名為 static 的文件夾,在應(yīng)用中使用 /static 即可訪問(wèn)。

給靜態(tài)文件生成 URL ,使用特殊的 'static' 端點(diǎn)名:

url_for('static', filename='style.css')

這個(gè)文件應(yīng)該存儲(chǔ)在文件系統(tǒng)上的 static/style.css 。

模板渲染?

用 Python 生成 HTML 十分無(wú)趣,而且相當(dāng)繁瑣,因?yàn)槟惚仨毷謩?dòng)對(duì) HTML 做轉(zhuǎn)義來(lái)保證應(yīng)用的安全。為此,F(xiàn)lask 配備了Jinja2 模板引擎。

你可以使用 render_template() 方法來(lái)渲染模板。你需要做的一切就是將模板名和你想作為關(guān)鍵字的參數(shù)傳入模板的變量。這里有一個(gè)展示如何渲染模板的簡(jiǎn)例:

from flask import render_template@app.route('/hello/')@app.route('/hello/')def hello(name=None):    return render_template('hello.html', name=name)

Flask 會(huì)在 templates 文件夾里尋找模板。所以,如果你的應(yīng)用是個(gè)模塊,這個(gè)文件夾應(yīng)該與模塊同級(jí);如果它是一個(gè)包,那么這個(gè)文件夾作為包的子目錄:

情況 1: 模塊:

/application.py/templates    /hello.html

情況 2: 包:

/application    /__init__.py    /templates        /hello.html

關(guān)于模板,你可以發(fā)揮 Jinja2 模板的全部實(shí)例。更多信息請(qǐng)見(jiàn)Jinja2 模板文檔

這里有一個(gè)模板實(shí)例:

{% if name %}  

Hello {{ name }}!

{% else %}

Hello World!

{% endif %}

在模板里,你也可以訪問(wèn) requestsessiong [1] 對(duì)象,以及 get_flashed_messages() 函數(shù)。

模板繼承讓模板用起來(lái)相當(dāng)順手。如欲了解繼承的工作機(jī)理,請(qǐng)?zhí)D(zhuǎn)到模板繼承 模式的文檔。最起碼,模板繼承能使特定元素(比如頁(yè)眉、導(dǎo)航欄和頁(yè)腳)可以出現(xiàn)在所有的頁(yè)面。

自動(dòng)轉(zhuǎn)義功能默認(rèn)是開(kāi)啟的,所以如果 name 包含 HTML ,它將會(huì)被自動(dòng)轉(zhuǎn)義。如果你能信任一個(gè)變量,并且你知道它是安全的(例如一個(gè)模塊把 Wiki 標(biāo)記轉(zhuǎn)換為 HTML),你可以用 Markup 類或 |safe 過(guò)濾器在模板中把它標(biāo)記為安全的。在 Jinja 2 文檔中,你會(huì)看到更多的例子。

這里是一個(gè) Markup 類如何使用的簡(jiǎn)單介紹:

>>> from flask import Markup>>> Markup('Hello %s!') % 'hacker'Markup(u'Hello <blink>hacker</blink>!')>>> Markup.escape('hacker')Markup(u'<blink>hacker</blink>')>>> Markup('Marked up ? HTML').striptags()u'Marked up \xbb HTML'

在 0.5 版更改: 自動(dòng)轉(zhuǎn)義不再在所有模板中啟用。下列擴(kuò)展名的模板會(huì)觸發(fā)自動(dòng)轉(zhuǎn)義:.html.htm 、.xml 、 .xhtml 。從字符串加載的模板會(huì)禁用自動(dòng)轉(zhuǎn)義。

[1]不確定 g 對(duì)象是什么?它允許你按需存儲(chǔ)信息,查看( g )對(duì)象的文檔和 在 Flask 中使用 SQLite 3 的文檔以獲取更多信息。

訪問(wèn)請(qǐng)求數(shù)據(jù)?

對(duì)于 Web 應(yīng)用,與客戶端發(fā)送給服務(wù)器的數(shù)據(jù)交互至關(guān)重要。在 Flask 中由全局的 request 對(duì)象來(lái)提供這些信息。如果你有一定的Python 經(jīng)驗(yàn),你會(huì)好奇,為什么這個(gè)對(duì)象是全局的,為什么 Flask 還能保證線程安全。答案是環(huán)境作用域:

環(huán)境局部變量?

內(nèi)幕

如果你想理解其工作機(jī)制及如何利用環(huán)境局部變量實(shí)現(xiàn)自動(dòng)化測(cè)試,請(qǐng)閱讀此節(jié),否則可跳過(guò)。

Flask 中的某些對(duì)象是全局對(duì)象,但卻不是通常的那種。這些對(duì)象實(shí)際上是特定環(huán)境的局部對(duì)象的代理。雖然很拗口,但實(shí)際上很容易理解。

想象一下處理線程的環(huán)境。一個(gè)請(qǐng)求傳入,Web 服務(wù)器決定生成一個(gè)新線程(或者別的什么東西,只要這個(gè)底層的對(duì)象可以勝任并發(fā)系統(tǒng),而不僅僅是線程)。當(dāng) Flask 開(kāi)始它內(nèi)部的請(qǐng)求處理時(shí),它認(rèn)定當(dāng)前線程是活動(dòng)的環(huán)境,并綁定當(dāng)前的應(yīng)用和 WSGI 環(huán)境到那個(gè)環(huán)境上(線程)。它的實(shí)現(xiàn)很巧妙,能保證一個(gè)應(yīng)用調(diào)用另一個(gè)應(yīng)用時(shí)不會(huì)出現(xiàn)問(wèn)題。

所以,這對(duì)你來(lái)說(shuō)意味著什么?除非你要做類似單元測(cè)試的東西,否則你基本上可以完全無(wú)視它。你會(huì)發(fā)現(xiàn)依賴于一段請(qǐng)求對(duì)象的代碼,因沒(méi)有請(qǐng)求對(duì)象無(wú)法正常運(yùn)行。解決方案是,自行創(chuàng)建一個(gè)請(qǐng)求對(duì)象并且把它綁定到環(huán)境中。單元測(cè)試的最簡(jiǎn)單的解決方案是:用 test_request_context() 環(huán)境管理器。結(jié)合 with 聲明,綁定一個(gè)測(cè)試請(qǐng)求,這樣你才能與之交互。下面是一個(gè)例子:

from flask import requestwith app.test_request_context('/hello', method='POST'):    # now you can do something with the request until the    # end of the with block, such as basic assertions:    assert request.path == '/hello'    assert request.method == 'POST'

另一種可能是:傳遞整個(gè) WSGI 環(huán)境給request_context() 方法:

from flask import requestwith app.request_context(environ):    assert request.method == 'POST'

請(qǐng)求對(duì)象?

API 章節(jié)對(duì)請(qǐng)求對(duì)象作了詳盡闡述(參見(jiàn) request ),因此這里不會(huì)贅述。此處寬泛介紹一些最常用的操作。首先從 flask 模塊里導(dǎo)入它:

from flask import request

當(dāng)前請(qǐng)求的 HTTP 方法可通過(guò) method 屬性來(lái)訪問(wèn)。通過(guò):attr:~flask.request.form 屬性來(lái)訪問(wèn)表單數(shù)據(jù)( POSTPUT 請(qǐng)求提交的數(shù)據(jù))。這里有一個(gè)用到上面提到的那兩個(gè)屬性的完整實(shí)例:

@app.route('/login', methods=['POST', 'GET'])def login():    error = None    if request.method == 'POST':        if valid_login(request.form['username'],                       request.form['password']):            return log_the_user_in(request.form['username'])        else:            error = 'Invalid username/password'    # the code below is executed if the request method    # was GET or the credentials were invalid    return render_template('login.html', error=error)

當(dāng)訪問(wèn) form 屬性中的不存在的鍵會(huì)發(fā)生什么?會(huì)拋出一個(gè)特殊的KeyError 異常。你可以像捕獲標(biāo)準(zhǔn)的 KeyError 一樣來(lái)捕獲它。如果你不這么做,它會(huì)顯示一個(gè) HTTP 400 Bad Request 錯(cuò)誤頁(yè)面。所以,多數(shù)情況下你并不需要干預(yù)這個(gè)行為。

你可以通過(guò) args 屬性來(lái)訪問(wèn) URL 中提交的參數(shù)( ?key=value ):

searchword = request.args.get('q', '')

我們推薦用 get 來(lái)訪問(wèn) URL 參數(shù)或捕獲 KeyError ,因?yàn)橛脩艨赡軙?huì)修改 URL,向他們展現(xiàn)一個(gè) 400 bad request 頁(yè)面會(huì)影響用戶體驗(yàn)。

欲獲取請(qǐng)求對(duì)象的完整方法和屬性清單,請(qǐng)參閱 request 的文檔。

文件上傳?

用 Flask 處理文件上傳很簡(jiǎn)單。只要確保你沒(méi)忘記在 HTML 表單中設(shè)置enctype="multipart/form-data" 屬性,不然你的瀏覽器根本不會(huì)發(fā)送文件。

已上傳的文件存儲(chǔ)在內(nèi)存或是文件系統(tǒng)中一個(gè)臨時(shí)的位置。你可以通過(guò)請(qǐng)求對(duì)象的 files 屬性訪問(wèn)它們。每個(gè)上傳的文件都會(huì)存儲(chǔ)在這個(gè)字典里。它表現(xiàn)近乎為一個(gè)標(biāo)準(zhǔn)的 Python file 對(duì)象,但它還有一個(gè) save() 方法,這個(gè)方法允許你把文件保存到服務(wù)器的文件系統(tǒng)上。這里是一個(gè)用它保存文件的例子:

from flask import request@app.route('/upload', methods=['GET', 'POST'])def upload_file():    if request.method == 'POST':        f = request.files['the_file']        f.save('/var/www/uploads/uploaded_file.txt')    ...

如果你想知道上傳前文件在客戶端的文件名是什么,你可以訪問(wèn)filename 屬性。但請(qǐng)記住,永遠(yuǎn)不要信任這個(gè)值,這個(gè)值是可以偽造的。如果你要把文件按客戶端提供的文件名存儲(chǔ)在服務(wù)器上,那么請(qǐng)把它傳遞給 Werkzeug 提供的secure_filename() 函數(shù):

from flask import requestfrom werkzeug import secure_filename@app.route('/upload', methods=['GET', 'POST'])def upload_file():    if request.method == 'POST':        f = request.files['the_file']        f.save('/var/www/uploads/' + secure_filename(f.filename))    ...

一些更好的例子,見(jiàn) 上傳文件 模式。

Cookies?

你可以通過(guò) cookies 屬性來(lái)訪問(wèn) Cookies,用響應(yīng)對(duì)象的 set_cookie 方法來(lái)設(shè)置 Cookies。請(qǐng)求對(duì)象的 cookies 屬性是一個(gè)內(nèi)容為客戶端提交的所有 Cookies 的字典。如果你想使用會(huì)話,請(qǐng)不要直接使用 Cookies,請(qǐng)參考 會(huì)話 一節(jié)。在 Flask 中,已經(jīng)注意處理了一些 Cookies 安全細(xì)節(jié)。

讀取 cookies:

from flask import request@app.route('/')def index():    username = request.cookies.get('username')    # use cookies.get(key) instead of cookies[key] to not get a    # KeyError if the cookie is missing.

存儲(chǔ) cookies:

from flask import make_response@app.route('/')def index():    resp = make_response(render_template(...))    resp.set_cookie('username', 'the username')    return resp

可注意到的是,Cookies 是設(shè)置在響應(yīng)對(duì)象上的。由于通常視圖函數(shù)只是返回字符串,之后 Flask 將字符串轉(zhuǎn)換為響應(yīng)對(duì)象。如果你要顯式地轉(zhuǎn)換,你可以使用 make_response() 函數(shù)然后再進(jìn)行修改。

有時(shí)候你想設(shè)置 Cookie,但響應(yīng)對(duì)象不能醋在。這可以利用延遲請(qǐng)求回調(diào) 模式實(shí)現(xiàn)。

為此,也可以閱讀 關(guān)于響應(yīng) 。

重定向和錯(cuò)誤?

你可以用 redirect() 函數(shù)把用戶重定向到其它地方。放棄請(qǐng)求并返回錯(cuò)誤代碼,用 abort() 函數(shù)。這里是一個(gè)它們?nèi)绾问褂玫睦?

from flask import abort, redirect, url_for@app.route('/')def index():    return redirect(url_for('login'))@app.route('/login')def login():    abort(401)    this_is_never_executed()

這是一個(gè)相當(dāng)無(wú)意義的例子因?yàn)橛脩魰?huì)從主頁(yè)重定向到一個(gè)不能訪問(wèn)的頁(yè)面(401 意味著禁止訪問(wèn)),但是它展示了重定向是如何工作的。

默認(rèn)情況下,錯(cuò)誤代碼會(huì)顯示一個(gè)黑白的錯(cuò)誤頁(yè)面。如果你要定制錯(cuò)誤頁(yè)面,可以使用 errorhandler() 裝飾器:

from flask import render_template@app.errorhandler(404)def page_not_found(error):    return render_template('page_not_found.html'), 404

注意 render_template() 調(diào)用之后的 404 。這告訴Flask,該頁(yè)的錯(cuò)誤代碼是 404 ,即沒(méi)有找到。默認(rèn)為 200,也就是一切正常。

關(guān)于響應(yīng)?

視圖函數(shù)的返回值會(huì)被自動(dòng)轉(zhuǎn)換為一個(gè)響應(yīng)對(duì)象。如果返回值是一個(gè)字符串,它被轉(zhuǎn)換為該字符串為主體的、狀態(tài)碼為 200 OK``的 、 MIME 類型是``text/html 的響應(yīng)對(duì)象。Flask 把返回值轉(zhuǎn)換為響應(yīng)對(duì)象的邏輯是這樣:

  1. 如果返回的是一個(gè)合法的響應(yīng)對(duì)象,它會(huì)從視圖直接返回。
  2. 如果返回的是一個(gè)字符串,響應(yīng)對(duì)象會(huì)用字符串?dāng)?shù)據(jù)和默認(rèn)參數(shù)創(chuàng)建。
  3. 如果返回的是一個(gè)元組,且元組中的元素可以提供額外的信息。這樣的元組必須是 (response, status, headers) 的形式,且至少包含一個(gè)元素。 status 值會(huì)覆蓋狀態(tài)代碼, headers 可以是一個(gè)列表或字典,作為額外的消息標(biāo)頭值。
  4. 如果上述條件均不滿足, Flask 會(huì)假設(shè)返回值是一個(gè)合法的 WSGI 應(yīng)用程序,并轉(zhuǎn)換為一個(gè)請(qǐng)求對(duì)象。

如果你想在視圖里操縱上述步驟結(jié)果的響應(yīng)對(duì)象,可以使用make_response() 函數(shù)。

譬如你有這樣一個(gè)視圖:

@app.errorhandler(404)def not_found(error):    return render_template('error.html'), 404

你只需要把返回值表達(dá)式傳遞給 make_response() ,獲取結(jié)果對(duì)象并修改,然后再返回它:

@app.errorhandler(404)def not_found(error):    resp = make_response(render_template('error.html'), 404)    resp.headers['X-Something'] = 'A value'    return resp

會(huì)話?

除請(qǐng)求對(duì)象之外,還有一個(gè) session 對(duì)象。它允許你在不同請(qǐng)求間存儲(chǔ)特定用戶的信息。它是在 Cookies 的基礎(chǔ)上實(shí)現(xiàn)的,并且對(duì)Cookies 進(jìn)行密鑰簽名。這意味著用戶可以查看你 Cookie 的內(nèi)容,但卻不能修改它,除非用戶知道簽名的密鑰。

要使用會(huì)話,你需要設(shè)置一個(gè)密鑰。這里介紹會(huì)話如何工作:

from flask import Flask, session, redirect, url_for, escape, requestapp = Flask(__name__)@app.route('/')def index():    if 'username' in session:        return 'Logged in as %s' % escape(session['username'])    return 'You are not logged in'@app.route('/login', methods=['GET', 'POST'])def login():    if request.method == 'POST':        session['username'] = request.form['username']        return redirect(url_for('index'))    return '''        

'''@app.route('/logout')def logout(): # remove the username from the session if it's there session.pop('username', None) return redirect(url_for('index'))# set the secret key. keep this really secret:app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

這里提到的 escape() 可以在你模板引擎外做轉(zhuǎn)義(如同本例)。

如何生成強(qiáng)壯的密鑰

隨機(jī)的問(wèn)題在于很難判斷什么是真隨機(jī)。一個(gè)密鑰應(yīng)該足夠隨機(jī)。你的操作系統(tǒng)可以基于一個(gè)密鑰隨機(jī)生成器來(lái)生成漂亮的隨機(jī)值,這個(gè)值可以用來(lái)做密鑰:

>>> import os>>> os.urandom(24)'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O

把這個(gè)值復(fù)制粘貼進(jìn)你的代碼中,你就有了密鑰。

使用基于 cookie 的會(huì)話需注意: Flask 會(huì)將你放進(jìn)會(huì)話對(duì)象的值序列化至Cookies。如果你發(fā)現(xiàn)某些值在請(qǐng)求之間并沒(méi)有持久存在,然而確實(shí)已經(jīng)啟用了Cookies,但也沒(méi)有得到明確的錯(cuò)誤信息。這時(shí),請(qǐng)檢查你的頁(yè)面響應(yīng)中的Cookies 的大小,并與 Web 瀏覽器所支持的大小對(duì)比。

消息閃現(xiàn)?

反饋,是良好的應(yīng)用和用戶界面的重要構(gòu)成。如果用戶得不到足夠的反饋,他們很可能開(kāi)始厭惡這個(gè)應(yīng)用。 Flask 提供了消息閃現(xiàn)系統(tǒng),可以簡(jiǎn)單地給用戶反饋。消息閃現(xiàn)系統(tǒng)通常會(huì)在請(qǐng)求結(jié)束時(shí)記錄信息,并在下一個(gè)(且僅在下一個(gè))請(qǐng)求中訪問(wèn)記錄的信息。展現(xiàn)這些消息通常結(jié)合要模板布局。

使用 flash() 方法可以閃現(xiàn)一條消息。要操作消息本身,請(qǐng)使用get_flashed_messages() 函數(shù),并且在模板中也可以使用。完整的例子見(jiàn) 消息閃現(xiàn) 部分。

日志記錄?

0.3 新版功能.

有時(shí)候你會(huì)處于這樣一種境地,你處理的數(shù)據(jù)本應(yīng)該是正確的,但實(shí)際上不是。比如,你會(huì)有一些向服務(wù)器發(fā)送請(qǐng)求的客戶端代碼,但請(qǐng)求顯然是畸形的。這可能是用戶篡改了數(shù)據(jù),或是客戶端代碼的粗制濫造。大多數(shù)情況下,正常地返回400 Bad Request 就可以了,但是有時(shí)候不能這么做,并且要讓代碼繼續(xù)運(yùn)行。

你可能依然想要記錄下,是什么不對(duì)勁。這時(shí)日志記錄就派上了用場(chǎng)。從Flask 0.3 開(kāi)始,F(xiàn)lask 就已經(jīng)預(yù)置了日志系統(tǒng)。

這里有一些調(diào)用日志記錄的例子:

app.logger.debug('A value for debugging')app.logger.warning('A warning occurred (%d apples)', 42)app.logger.error('An error occurred')

附帶的 logger 是一個(gè)標(biāo)準(zhǔn)日志類Logger ,所以更多信息請(qǐng)查閱 logging的文檔 。

整合 WSGI 中間件?

如果你想給你的應(yīng)用添加 WSGI 中間件,你可以封裝內(nèi)部 WSGI 應(yīng)用。例如若是你想用 Werkzeug 包中的某個(gè)中間件來(lái)應(yīng)付 lighttpd 中的 bugs ,可以這樣做:

from werkzeug.contrib.fixers import LighttpdCGIRootFixapp.wsgi_app = LighttpdCGIRootFix(app.wsgi_app)

部署到 Web 服務(wù)器?

準(zhǔn)備好部署你的 Flask 應(yīng)用了?你可以立即部署到托管平臺(tái)來(lái)圓滿完成快速入門(mén),以下廠商均向小項(xiàng)目提供免費(fèi)的方案:

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
超實(shí)用的Flask入門(mén)基礎(chǔ)教程,新手必備!
使用 Meteor 輕松開(kāi)發(fā)實(shí)時(shí)網(wǎng)站
讓我告訴你建一個(gè)小網(wǎng)站有多么容易
Discuz! X模板中的一些基本語(yǔ)法
C++ 知識(shí)
django
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服