亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Flask Web Development —— 基本應(yīng)用程序結(jié)構(gòu)(下)

caohaoyu / 3363人閱讀

摘要:有兩類應(yīng)用級(jí)和請(qǐng)求級(jí)。一個(gè)響應(yīng)中非常重要的部分是狀態(tài)碼,默認(rèn)設(shè)置來(lái)指示請(qǐng)求已經(jīng)成功處理。重定向通常由響應(yīng)狀態(tài)碼注明并且重定向的由頭部的給出。因?yàn)檫@些變化,應(yīng)用程序獲得一組基本的命令行選項(xiàng)。運(yùn)行顯示可用信息在應(yīng)用程序上下文的內(nèi)部運(yùn)行一個(gè)。

5、請(qǐng)求-響應(yīng)循環(huán)

現(xiàn)在你已經(jīng)玩過(guò)一個(gè)基本的Flask應(yīng)用程序,你也許想要知道更多關(guān)于Flask如何施展魔力。下面章節(jié)描述了一些框架設(shè)計(jì)方面的特點(diǎn)。

5.1、應(yīng)用程序Context和請(qǐng)求Context

當(dāng)Flask從客戶端收到一個(gè)請(qǐng)求,它需要提供幾個(gè)可用對(duì)象給視圖函數(shù)處理。request對(duì)象是個(gè)不錯(cuò)的例子,它封裝了客戶端發(fā)送的HTTP請(qǐng)求。

Flask視圖函數(shù)訪問(wèn)request對(duì)象的最好方式,就是作為一個(gè)參數(shù)發(fā)送它,但這需要每個(gè)單一視圖函數(shù)在應(yīng)用程序中有一個(gè)額外的參數(shù)??紤]一下,如果request對(duì)象不是唯一一個(gè)視圖函數(shù)需要訪問(wèn)完成請(qǐng)求的對(duì)象,事情將會(huì)變得更加復(fù)雜。

為了避免弄亂視圖函數(shù)那些可能需要或不需要的參數(shù),F(xiàn)lask使用context來(lái)臨時(shí)確定可訪問(wèn)的全局對(duì)象。也多虧了context,視圖函數(shù)可以寫成下面這樣:

from flask import request

@app.route("/")
def index():
    user_agent = request.headers.get("User-Agent")
    return "

Your browser is %s

" % user_agent

注意,在這個(gè)視圖函數(shù)中,request是如何被作為一個(gè)全局變量來(lái)使用的?,F(xiàn)實(shí)中,request是不能作為全局變量的,如果是多線程服務(wù)器,同一時(shí)間線程作用于不同客戶端的不同請(qǐng)求,所以每一個(gè)線程需要看到request中的不同對(duì)象。contexts使得Flask確定可訪問(wèn)的全局變量而不干擾其他線程。

  

注:線程是可以獨(dú)立管理的最小指令序列。一個(gè)進(jìn)程中有多個(gè)活動(dòng)的線程是非常常見(jiàn)的,有時(shí)分享內(nèi)存或文件句柄資源。多線程web服務(wù)器會(huì)啟動(dòng)一個(gè)線程池并從池中選擇一個(gè)線程來(lái)處理每個(gè)傳入的請(qǐng)求。

Flask有兩類context:應(yīng)用級(jí)context請(qǐng)求級(jí)context。表2-1展示了這些context提供的變量。

表2-1. Flask全局context

Flask激活(或壓棧)應(yīng)用級(jí)context和請(qǐng)求級(jí)context在調(diào)度請(qǐng)求之前,然后刪除他們當(dāng)請(qǐng)求被處理后。當(dāng)應(yīng)用程序context被壓入棧,線程中current_appg變量變得可用;同樣的,當(dāng)請(qǐng)求級(jí)context被壓入棧,requestsession變量也同樣變得可用。如果這些變量中的任何一個(gè)不是由激活的應(yīng)用級(jí)或請(qǐng)求級(jí)context訪問(wèn),會(huì)產(chǎn)生錯(cuò)誤。在后面的章節(jié)會(huì)詳細(xì)討論四個(gè)context變量,所以不要擔(dān)心你不理解它們的用處。

下面的Python shell會(huì)話演示了應(yīng)用級(jí)context是如何工作的:

>>> from hello import app
>>> from flask import current_app
>>> current_app.name
Traceback (most recent call last):
...
RuntimeError: working outside of the application context
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
"hello"
>>> app_ctx.pop()

在這個(gè)示例中,當(dāng)應(yīng)用級(jí)context沒(méi)有激活,但是卻作為有效的context被壓入棧中,current_app.name報(bào)錯(cuò)。注意在應(yīng)用程序?qū)嵗幸粋€(gè)應(yīng)用級(jí)context是如何通過(guò)調(diào)用app.app_context()來(lái)獲得的。

5.2、請(qǐng)求調(diào)度

當(dāng)一個(gè)應(yīng)用程序收到客戶端的請(qǐng)求,它需要找到響應(yīng)的視圖函數(shù)為之服務(wù)。對(duì)于這個(gè)任務(wù),F(xiàn)lask會(huì)在應(yīng)用程序的URL映射中查找請(qǐng)求的URL,該映射包含URLs和操作它們的視圖函數(shù)。Flask通過(guò)app.route裝飾器或非裝飾器版本app.add_url_rule()來(lái)建立這個(gè)映射。

看一下Flask應(yīng)用程序中URL映射是怎樣的,你可以在Python shell中檢查hello.py創(chuàng)建的映射。測(cè)試中,請(qǐng)確保你的虛擬環(huán)境是激活狀態(tài):

(venv) % python
>>> from hello import app
>>> app.url_map
Map([ index>,
  " (HEAD, OPTIONS, GET) -> static>,
  " (HEAD, OPTIONS, GET) -> user>])

//user/路由是由應(yīng)用程序中的app.route所定義。/static/路由是由Flask添加,用于訪問(wèn)靜態(tài)文件的一個(gè)特殊路由。你將在第三章學(xué)習(xí)更多關(guān)于靜態(tài)文件的內(nèi)容。

URL映射中所示的HEAD、OPTIONS、GET元素為request方法,由路由處理。Flask連接方法到每個(gè)路由,這樣不同的請(qǐng)求方法發(fā)送到相同的URL可以被不同的視圖函數(shù)處理。HEADOPTIONS方法由Flask自動(dòng)管理,所以實(shí)際上可以說(shuō),在這個(gè)應(yīng)用程序中URL映射的三個(gè)路由都連接到GET方法了。在第四章你將學(xué)習(xí)為路由指定不同的請(qǐng)求方法。

5.3、請(qǐng)求Hooks

有些時(shí)候在每個(gè)請(qǐng)求處理之前或之后執(zhí)行代碼是非常有用的。例如,在開始每一個(gè)請(qǐng)求前可能有必要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)連接,或?qū)τ脩粽?qǐng)求進(jìn)行驗(yàn)證。為了避免復(fù)制處理這些操作的代碼到每一個(gè)視圖函數(shù)中,F(xiàn)lask給你選擇注冊(cè)相同函數(shù)來(lái)調(diào)用,在請(qǐng)求被分配給視圖函數(shù)之前或之后。

請(qǐng)求hooks由裝飾器實(shí)現(xiàn)。下面是四個(gè)Flask支持的hooks:

before_first_request:在第一個(gè)請(qǐng)求被處理前注冊(cè)一個(gè)函數(shù)運(yùn)行。

before_request:在每一個(gè)請(qǐng)求前注冊(cè)一個(gè)函數(shù)運(yùn)行。

after_request:如果沒(méi)有未處理的異常發(fā)生,在每一個(gè)請(qǐng)求后注冊(cè)一個(gè)函數(shù)運(yùn)行。

teardown_request:即使未處理的異常發(fā)生,在每一個(gè)請(qǐng)求后注冊(cè)一個(gè)函數(shù)運(yùn)行。

在請(qǐng)求hook函數(shù)和視圖函數(shù)之間共享數(shù)據(jù)的慣用方法就是使用g全局context。例如,before_request處理程序可以從數(shù)據(jù)庫(kù)加載已登錄的用戶并保存在g.user中。之后,當(dāng)視圖函數(shù)被調(diào)用,可以從那訪問(wèn)用戶。

請(qǐng)求hooks的示例會(huì)在未來(lái)的章節(jié)中展示給大家,所以不用擔(dān)心,

5.4、響應(yīng)

當(dāng)Flask調(diào)用一個(gè)視圖函數(shù),并期望它的返回值去響應(yīng)該請(qǐng)求。大多數(shù)的響應(yīng)是將簡(jiǎn)單字符串構(gòu)成的HTML頁(yè)面發(fā)回給客戶端。

但是HTTP協(xié)議需要比字符串更多的信息作為請(qǐng)求的響應(yīng)。一個(gè)HTTP響應(yīng)中非常重要的部分是狀態(tài)碼,F(xiàn)lask默認(rèn)設(shè)置200來(lái)指示請(qǐng)求已經(jīng)成功處理。

當(dāng)視圖函數(shù)需要用不同的狀態(tài)碼響應(yīng),可以在響應(yīng)文本后添加數(shù)字碼作為第二個(gè)返回值。例如,下面的視圖函數(shù)返回400錯(cuò)誤狀態(tài)碼的請(qǐng)求:

@app.route("/")
def index():
    return "

Bad Request

", 400

視圖函數(shù)返回的響應(yīng)還可以攜帶第三個(gè)參數(shù),添加一個(gè)頭部字典給HTTP響應(yīng)。通常很少用到,但是你可以在第十四章看到示例。

除了返回一個(gè)、兩個(gè)或三個(gè)值的元組,F(xiàn)lask視圖函數(shù)可以選擇返回response對(duì)象make_response()函數(shù)可攜帶一個(gè)、兩個(gè)或三個(gè)參數(shù),和視圖函數(shù)返回的值一樣,并返回一個(gè)response對(duì)象。有時(shí)候在視圖函數(shù)中執(zhí)行這個(gè)轉(zhuǎn)換是非常有用的,然后使用response對(duì)象中的方法進(jìn)一步配置響應(yīng)。下面的示例創(chuàng)建response對(duì)象并設(shè)置cookie:

from flask import make_response

@app.route("/")
def index():
    response = make_response("

This document carries a cookie!

") response.set_cookie("answer", "42") return response

有一類特殊的響應(yīng)稱作重定向。這類響應(yīng)不包含頁(yè)面文檔;只是給瀏覽器一個(gè)新的URL去加載新的頁(yè)面。重定向通常和web表單一起使用,你將在第四章學(xué)習(xí)。

重定向通常由302響應(yīng)狀態(tài)碼注明并且重定向的URL由頭部的Location給出。重定向響應(yīng)可以使用三個(gè)值的返回生成,也可通過(guò)響應(yīng)對(duì)象生成,但是鑒于它頻繁的使用,F(xiàn)lask提供redirect()函數(shù)來(lái)創(chuàng)建這樣的響應(yīng):

from flask import redirect

@app.route("/")
def index():
    return redirect("http://www.example.com")

另一個(gè)具有中斷功能的特殊響應(yīng)用來(lái)錯(cuò)誤處理。下面的示例,當(dāng)URL給出的id動(dòng)態(tài)參數(shù)不是一個(gè)合法的用戶時(shí)返回狀態(tài)碼404:

from flask import abort

@app.route("/user/")
def get_user(id):
    user = load_user(id)
    if not user:
        abort(404)
    return "

Hello, %s

" % user.name

注意終止不是指將控制權(quán)返回給調(diào)用它的函數(shù),而是指通過(guò)拋出異常將控制權(quán)返回給web服務(wù)。

6、Flask擴(kuò)展

Flask是可擴(kuò)展的。它故意騰出地給重要的功能,例如數(shù)據(jù)庫(kù)和用戶授權(quán),給你自由去選擇最適合你的應(yīng)用程序的包,或?qū)懸粋€(gè)自己想要的。

社區(qū)開發(fā)了非常多的擴(kuò)展用于各種用途,如果這還不夠,可以使用任何Python標(biāo)準(zhǔn)包和庫(kù)。為了讓你了解一個(gè)擴(kuò)展是如何并入一個(gè)應(yīng)用程序的,下面的章節(jié)給hello.py添加一個(gè)擴(kuò)展,增加應(yīng)用程序的命令行參數(shù)。

6.1、Flask-Script命令行選項(xiàng)

Flask開發(fā),其web服務(wù)器支持一系列的啟動(dòng)配置選項(xiàng),但是配置它們的唯一方式只有在腳本中傳遞參數(shù)給app.run()并調(diào)用。這不是非常的方便,理想方法是通過(guò)命令行參數(shù)傳遞配置選項(xiàng)。

Flask-Script是給你的Flask應(yīng)用程序添加命令行解釋的擴(kuò)展。它打包了一組通用的選項(xiàng),還支持自定義命令。

使用pip安裝擴(kuò)展:

(venv) $ pip install flask-script

示例2-3展示了在 hello.py 應(yīng)用程序中添加命令行解釋的變化。

示例2-3. hello.py:使用Flask-Script

from flask.ext.script import Manager

manager = Manager(app)

# ...

if __name__ == "__main__":
    manager.run()

專為Flask開發(fā)的擴(kuò)展暴露在flask.ext命名空間下。Flask-Script從flask.ext.script中導(dǎo)出一個(gè)名為Manager的類。

初始化這個(gè)擴(kuò)展的方法和其他許多擴(kuò)展一樣:主類實(shí)例的初始化是通過(guò)將應(yīng)用程序?qū)嵗鳛閰?shù)傳遞給構(gòu)造函數(shù)實(shí)現(xiàn)的。創(chuàng)建的對(duì)象適當(dāng)?shù)挠糜诿恳粋€(gè)擴(kuò)展。在這個(gè)示例中,服務(wù)器啟動(dòng)通過(guò)manager.run()來(lái)路由,且命令行在這被解析。

  

建議:如果你有克隆在GitHub上的應(yīng)用程序,你現(xiàn)在可以運(yùn)行git checkout 2c來(lái)切換到這個(gè)版本的應(yīng)用程序。

因?yàn)檫@些變化,應(yīng)用程序獲得一組基本的命令行選項(xiàng)。運(yùn)行hello.py顯示可用信息:

$ python hello.py
usage: hello.py [-h] {shell, runserver} ...

positional arguments:
  {shell, runserver}
    shell           在Flask應(yīng)用程序上下文的內(nèi)部運(yùn)行一個(gè)Python Shell。
    runserver       運(yùn)行Flask開發(fā)服務(wù)器,例如:app.run()

optional arguments:
  -h, --help        顯示這個(gè)幫助信息并退出

shell命令用于在應(yīng)用程序上下文中啟動(dòng)一個(gè)Python shell會(huì)話。你可以使用這個(gè)會(huì)話去運(yùn)行維護(hù)任務(wù),或測(cè)試,或調(diào)試錯(cuò)誤。

runserver命令,就像它的名稱一樣,啟動(dòng)web服務(wù)。運(yùn)行python hello.py runserver在調(diào)試模式下啟動(dòng)web服務(wù),還有更多的選項(xiàng):

(venv) $ python hello.py runserver --help
usage: hello.py runserver [-h] [-t HOST] [-p PORT] [--threaded]
                          [--processes PROCESSES] [--passthrough-errors] [-d]
                          [-r]

運(yùn)行Flask開發(fā)服務(wù)器,例如:app.run()

optional arguments:
  -h, --help             顯示這個(gè)幫助信息并退出
  -t HOST, --host HOST
  -p PORT, --port PORT
  --threaded
  --processes PROCESSES
  --passthrough-errors
  -d, --no-debug
  -r, --no-reload 

--host參數(shù)是一個(gè)非常有用的選項(xiàng),因?yàn)樗芨嬖Vweb服務(wù)器監(jiān)聽(tīng)哪個(gè)網(wǎng)絡(luò)接口的客戶端連接。默認(rèn),F(xiàn)lask開發(fā)的web服務(wù)器監(jiān)聽(tīng)localhost的連接,所以只有來(lái)自內(nèi)部計(jì)算機(jī)運(yùn)行的服務(wù)器可以接收。下面的命令使得web服務(wù)器監(jiān)聽(tīng)公網(wǎng)接口,其他網(wǎng)絡(luò)上的計(jì)算機(jī)可以連接:

(venv) $ python hello.py runserver --host 0.0.0.0
 * Running on http://0.0.0.0:5000/
 * Restarting with reload

現(xiàn)在web服務(wù)器應(yīng)該可以從網(wǎng)絡(luò)中的任何一臺(tái)計(jì)算機(jī)訪問(wèn) http://a.b.c.d:5000 ,“a.b.c.d”是運(yùn)行服務(wù)的計(jì)算機(jī)的外部IP地址。

這一章介紹了請(qǐng)求響應(yīng)的概念,但說(shuō)的更多的是響應(yīng)。Flask使用模板為生成響應(yīng)提供非常好的支持,這是非常重要的話題,下一章會(huì)重點(diǎn)講它。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/37441.html

相關(guān)文章

  • Flask Web Development —— 基本應(yīng)用程序結(jié)構(gòu)(上)

    摘要:注對(duì)于開發(fā)者來(lái)說(shuō),傳給應(yīng)用程序構(gòu)造函數(shù)的參數(shù)是比較容易弄混淆的。在應(yīng)程序中定義路由的最便捷的方式是通過(guò)顯示定義在應(yīng)用程序?qū)嵗系难b飾器,注冊(cè)被裝飾的函數(shù)來(lái)作為一個(gè)路由。一個(gè)常見(jiàn)的模式是使用裝飾器來(lái)注冊(cè)函數(shù)作為一個(gè)事件處理程序。 在這一章,你將學(xué)習(xí)Flask應(yīng)用程序不同部分。同時(shí)你將編寫和運(yùn)行你的第一個(gè)Flask web應(yīng)用程序。 1、初始化 在這章,你將學(xué)到Flask應(yīng)用程序的不...

    NusterCache 評(píng)論0 收藏0
  • Flask Web Development —— 大型應(yīng)用程序結(jié)構(gòu)(上)

    摘要:被定義在包的構(gòu)造函數(shù)中的應(yīng)用程序工廠函數(shù)會(huì)在示例中展示。這個(gè)構(gòu)造函數(shù)導(dǎo)入大部分當(dāng)前需要使用的擴(kuò)展,但因?yàn)闆](méi)有應(yīng)用程序?qū)嵗跏蓟鼈?,它可以被?chuàng)建但不初始化通過(guò)不傳遞參數(shù)給它們的構(gòu)造函數(shù)。而應(yīng)用程序范圍內(nèi)的錯(cuò)誤處理則必須使用。 雖然小型web應(yīng)用程序用單個(gè)腳本可以很方便,但這種方法卻不能很好地?cái)U(kuò)展。隨著應(yīng)用變得復(fù)雜,在單個(gè)大的源文件中處理會(huì)變得問(wèn)題重重。 與大多數(shù)其他web框架不同,F(xiàn)l...

    chemzqm 評(píng)論0 收藏0
  • Flask Web Development —— 大型應(yīng)用程序結(jié)構(gòu)

    摘要:?jiǎn)卧獪y(cè)試這個(gè)應(yīng)用非常小以至于不需要太多的測(cè)試,但是作為示例會(huì)在示例中展示兩個(gè)簡(jiǎn)單的測(cè)試定義。示例單元測(cè)試編寫好的測(cè)試使用的是來(lái)自于標(biāo)準(zhǔn)庫(kù)中標(biāo)準(zhǔn)的包。為了運(yùn)行單元測(cè)試,可以在腳本中增加一個(gè)自定義的命令。 4、啟動(dòng)腳本 頂層目錄中的manage.py文件用于啟動(dòng)應(yīng)用。這個(gè)腳本會(huì)在示例7-8中展示。 示例7-8. manage.py:?jiǎn)?dòng)腳本 #!/usr/bin/env python im...

    whidy 評(píng)論0 收藏0
  • Flask Web Development —— 模板(中)

    摘要:示例使用的模板的指令通過(guò)從引用來(lái)實(shí)現(xiàn)模板的繼承。上面的模板定義了三個(gè),分別命名為和。同時(shí)返回相應(yīng)錯(cuò)誤的數(shù)字狀態(tài)碼。示例帶有導(dǎo)航欄的基礎(chǔ)應(yīng)用程序模板這個(gè)模板中的塊中只是一個(gè)名為的元素,它包含了在派生模板中定義的名為的空。 2、集成Twitter Bootstrap的Flask-Bootstrap Bootstrap是Twitter的一個(gè)開源框架,提供用戶交互組件來(lái)創(chuàng)建一個(gè)清新且有吸引力...

    eternalshallow 評(píng)論0 收藏0
  • Flask Web Development —— 模板(上)

    摘要:用真實(shí)的值替換變量并返回最終響應(yīng)字符串,這個(gè)過(guò)程稱為渲染。示例展示模板實(shí)現(xiàn)該響應(yīng)??刂平Y(jié)構(gòu)提供一些控制結(jié)構(gòu)用于改變模板流。這個(gè)示例展示如何使用循環(huán)做到這些同樣支持宏,這和代碼中的函數(shù)很像。 寫代碼最關(guān)鍵的是要易于維護(hù)且結(jié)構(gòu)清晰整潔。目前為止,你看到的例子都過(guò)于簡(jiǎn)單從而沒(méi)有做這方面的要求。Flask視圖函數(shù)希望將兩個(gè)應(yīng)該完全獨(dú)立的任務(wù)一并處理,兩個(gè)任務(wù)有兩種代碼,一并處理勢(shì)必會(huì)引發(fā)問(wèn)題。...

    fizz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<