python-flask學習(一)

 

Flask-(狗書學習)html

Flask 自開發伊始就被設計爲可擴展的框架,它具備一個包含基本服務的強健核心,其餘功能則可經過擴展實現。你能夠本身挑選所需的擴展包,組成一個沒有附加功能的精益組合,從而徹底精確知足自身需求。
 
Flask 有兩個主要依賴:路由、調試和 Web 服務器網關接口
子系統由 Werkzeug(http://werkzeug.pocoo.org/)提供;模板系統由 Jinja2(http://jinja.pocoo.org/)提供
 

1.1 初始化

 
 
全部 Flask 程序都必須建立一個程序實例。Web 服務器使用一種名爲 Web 服務器網關接口
 
 
(Web Server Gateway Interface,WSGI)的協議,把接收自客戶端的全部請求都轉交給這
 
 
個對象處理。程序實例是 Flask 類的對象,常用下述代碼建立:
from flask import Flask app = Flask(__name__)
Flask 類的構造函數只有一個必須指定的參數,即程序主模塊或包的名字。在大多數程
中,Python 的 __name__ 變量就是所需的值。
 
Flask 用這個參數決定程序的根目錄,以便稍後可以找到相對於程序根目錄的資源文件位置
 

1.2 路由和視圖函數

 
 客戶端(例如 Web 瀏覽器)把請求發送給 Web 服務器,Web 服務器再把請求發送給 Flask程序實例。
 
程序實例須要知道對每一個 URL 請求運行哪些代碼,因此保存了一個 URL 到 Python 函數的映射關係.處理 URL 和函數之間關係的程序稱爲路由.
 
在 Flask 程序中定義路由的最簡便方式,是使用程序實例提供的 app.route 修飾器,把修 飾的函數註冊爲路由.下面的例子說明了如何使用這個修飾器聲明路由:
 
修飾器是 Python 語言的標準特性,可使用不一樣的方式修改函數的行爲.慣 經常使用法是使用修飾器把函數註冊爲事件的處理程序.
 
@app.route('/') def index(): return '<h1>Hello World!</h1>'

前例把 index() 函數註冊爲程序根地址的處理程序.若是部署程序的服務器域名爲 www. example.com,在瀏覽器中訪問 http://www.example.com 後,會觸發服務器執行 index() 函 數.python

這個函數的返回值稱爲響應,是客戶端接收到的內容.若是客戶端是 Web 瀏覽器,響 應就是顯示給用戶查看的文檔.數據庫

也就是若是在「/」後添加各類自定義路徑就能夠實現返回本身定義的不一樣函數。flask

像 index() 這樣的函數稱爲視圖函數(view function)。視圖函數返回的響應能夠是包含HTML 的簡單字符串,也能夠是複雜的表單
 
 

注意:在 Python 代碼中嵌入響應字符串會致使代碼難以維護,此處這麼作只是爲了介紹響應的概念。瀏覽器

 

動態地址:服務器

Flask 支持這種形式的 URL,只需在 route 修飾器中使用特 殊的句法便可.下例定義的路由中cookie

<name>

就是動態名字:session

@app.route('/user/<name>') def user(name): return '<h1>Hello, %s!</h1>' % name

尖括號中的內容就是動態部分,任何能匹配靜態部分的 URL 都會映射到這個路由上.調 用視圖函數多線程

user(name)

時,Flask 會將動態部分做爲參數傳入函數.在這個視圖函數中,參數用於生成針對我的的歡迎消息.app

路由中的動態部分默認使用字符串,不過也可以使用類型定義.例如,路由 /user/<int:id> 只會匹配動態片斷 id 爲整數的 URL.

Flask 支持在路由中使用 int,float 和 path 類型. path 類型也是字符串,但不把斜線視做分隔符,而將其看成動態片斷的一部分.

2.3 啓動服務器

程序實例用 run 方法啓動 Flask 集成的開發 Web 服務器:
if __name__ == '__main__' app.run(debug=True)

 

__name__=='__main__' 是 Python 的慣經常使用法,在這裏確保直接執行這個腳本時才啓動開發Web 服務器。
若是這個腳本由其餘腳本引入,程序假定父級腳本會啓動不一樣的服務器,所以不會執行 app.run()。
 
服務器啓動後,會進入輪詢,等待並處理請求.輪詢會一直運行,直到程序中止,好比按 Ctrl-C 鍵.
有一些選項參數可被 app.run() 函數接受用於設置 Web 服務器的操做模式.
在開發過程當中 啓用調試模式會帶來一些便利,好比說激活調試器和重載程序.要想啓用調試模式,咱們 能夠把 debug 參數設爲 True.例如:
app.run(host='0.0.0.0',port=80,debug=True)

2.4 請求-響應循環

2.5.1 程序和請求上下文

Flask 從客戶端收到請求時,要讓視圖函數能訪問一些對象,這樣才能處理請求.請求對象就是一個很好的例子,它封裝了客戶端發送的 HTTP 請求.
要想讓視圖函數可以訪問請求對象,一個顯而易見的方式是將其做爲參數傳入視圖函數,
不過這會致使程序中的每一個視圖函數都增長一個參數.除了訪問請求對象,若是視圖函數在處理請求時還要訪問其餘對象,狀況會變得更糟.

爲了不大量無關緊要的參數把視圖函數弄得一團糟,Flask 使用上下文臨時把某些對象 變爲全局可訪問.有了上下文,就能夠寫出下面的視圖函數:

from flask import request @app.route('/') def index(): user_agent = request.headers.get('User-Agent') return '<p>Your browser is %s</p>' % user_agent

 注意在這個視圖函數中咱們如何把 request 看成全局變量使用.事實上,request 不多是 全局變量.試想,在多線程服務器中,多個線程同時處理不一樣客戶端發送的不一樣請求時, 每一個線程看到的 request 對象必然不一樣.

Falsk 使用上下文讓特定的變量在一個線程中全局 可訪問,與此同時卻不會干擾其餘線程.

線程:線程是可單獨管理的最小指令集.進程常用多個活動線程,有時還會共 享內存或文件句柄等資源.多線程 Web 服務器會建立一個線程池,再從線 程池中選擇一個線程用於處理接收到的請求.

 

在 Flask 中有兩種上下文:程序上下文和請求上下文。

Flask 在分發請求以前激活(或推送)程序和請求上下文,請求處理完成後再將其刪除.

程序上下文被推送後,就能夠在線程中使用 current_app 和 g 變量.相似地,

請求上下文被推送後,就可使用 request 和 session 變量.

若是使用這些變量時咱們沒有激活程序上 下文或請求上下文,就會致使錯誤.

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

 

在這個例子中,沒激活程序上下文以前就調用 current_app.name 會致使錯誤,但推送完上 下文以後就能夠調用了.

注意:在程序實例上調用 app.app_context() 可得到一個程序上 下文.

2.4.2 請求調度

程序收到客戶端發來的請求時,要找處處理該請求的視圖函數.爲了完成這個任務,Flask 會在程序的 URL 映射中查找請求的 URL.

URL 映射是 URL 和視圖函數之間的對應關係. Flask 使用 app.route 修飾器或者非修飾器形式的 app.add_url_rule() 生成映射.

(venv) $ python >>> from hello import app >>> app.url_map Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>, <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>, <Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])

/ 和 /user/<name> 路由在程序中使用 app.route 修飾器定義./static/<filename> 路由是 Flask 添加的特殊路由,用於訪問靜態文件.

URL 映射中的 HEAD,Options,GET 是請求方法,由路由進行處理.Flask 爲每一個路由都指 定了請求方法,這樣不一樣的請求方法發送到相同的 URL 上時,會使用不一樣的視圖函數進行處理.

HEADOPTIONS 方法由 Flask 自動處理,所以能夠這麼說,在這個程序中,URL 映射中的 3 個路由都使用 GET 方法.

2.5.3 請求鉤子

有時在處理請求以前或以後執行代碼會頗有用.例如,在請求開始時,咱們可能須要創 建數據庫鏈接或者認證發起請求的用戶.爲了不在每一個視圖函數中都使用重複的代碼, Flask 提供了註冊通用函數的功能,註冊的函數可在請求被分發到視圖函數以前或以後 調用.
 
請求鉤子使用修飾器實現.Flask 支持如下 4 種鉤子.
 
• before_first_request:註冊一個函數,在處理第一個請求以前運行。
 
• before_request:註冊一個函數,在每次請求以前運行。
 
• after_request:註冊一個函數,若是沒有未處理的異常拋出,在每次請求以後運行。
 
• teardown_request:註冊一個函數,即便有未處理的異常拋出,也在每次請求以後運行。
 

 在請求鉤子函數和視圖函數之間共享數據通常使用上下文全局變量 g.例如,before_ request 處理程序能夠從數據庫中加載已登陸用戶,並將其保存到 g.user 中.隨後調用視 圖函數時,視圖函數再使用 g.user 獲取用戶.

 

2.5.4 響應

 Flask 調用視圖函數後,會將其返回值做爲響應的內容.大多數狀況下,響應就是一個簡單的字符串,做爲 HTML 頁面回送客戶端.例如

return redirect(url_for('admin.list_entries'))# admin.list_entries是html頁面

但 HTTP 協議須要的不只是做爲請求響應的字符串.HTTP 響應中一個很重要的部分是狀 態碼,Flask 默認設爲 200,這個代碼代表請求已經被成功處理.

 

若是視圖函數返回的響應須要使用不一樣的狀態碼,那麼能夠把數字代碼做爲第二個返回 值,添加到響應文本以後.例如,下述視圖函數返回一個 400 狀態碼,表示請求無效:

@app.route('/') def index(): return '<h1>Bad Request</h1>', 400

 

 視圖函數返回的響應還可接受第三個參數,這是一個由首部(header)組成的字典,能夠 添加到 HTTP 響應中.通常狀況下並不須要這麼作

 

 若是不想返回由 1 個,2 個或 3 個值組成的元組,Flask 視圖函數還能夠返回 Response 對 象.

 make_response() 函數可接受 1 個,2 個或 3 個參數(和視圖函數的返回值同樣),並 返回一個 Response 對象.有時咱們須要在視圖函數中進行這種轉換,而後在響應對象上調 用各類方法,進一步設置響應.

下例建立了一個響應對象,而後設置了 cookie:

 

from flask import make_response @app.route('/') def index(): response = make_response('<h1>This document carries a cookie!</h1>') response.set_cookie('answer', '42') return response

 

 有一種名爲重定向的特殊響應類型.這種響應沒有頁面文檔,只告訴瀏覽器一個新地址用 以加載新頁面.重定向常常在 Web 表單中使用

 

 重定向常用 302 狀態碼錶示,指向的地址由 Location 首部提供.重定向響應可使用 3 個值形式的返回值生成,也可在 Response 對象中設定.

 不過,因爲使用頻繁,Flask 提 供了 redirect() 輔助函數,用於生成這種響應:

 

from flask import redirect @app.route('/') def index(): return redirect('http://www.example.com')

 

 還有一種特殊的響應由 abort 函數生成,用於處理錯誤.在下面這個例子中,若是 URL 中 動態參數 id 對應的用戶不存在,就返回狀態碼 404:

from flask import abort @app.route('/user/<id>') def get_user(id): user = load_user(id) if not user: abort(404) return '<h1>Hello, %s</h1>' % user.name

 

注意:abort 不會把控制權交還給調用它的函數,而是拋出異常把控制權交給 Web 服 務器

2.6 Flask擴展

Flask 被設計爲可擴展形式,故而沒有提供一些重要的功能,例如數據庫和用戶認證,所 以開發者能夠自由選擇最適合程序的包,或者按需求自行開發.

 

社區成員開發了大量不一樣用途的擴展,若是這還不能知足需求,你還可以使用全部 Python 標準包或代碼庫。
 
使用Flask-Script支持命令行選項
 
Flask 的開發 Web 服務器支持不少啓動設置選項,但只能在腳本中做爲參數傳給 app.run() 函數.這種方式並不十分方便,傳遞設置選項的理想方式是使用命令行參數.
 
Flask-Script 是一個 Flask 擴展,爲 Flask 程序添加了一個命令行解析器.Flask-Script 自帶 了一組經常使用選項,並且還支持自定義命令.
相關文章
相關標籤/搜索