Flask-(狗書學習)html
from flask import Flask app = Flask(__name__)
@app.route('/') def index(): return '<h1>Hello World!</h1>'
前例把 index() 函數註冊爲程序根地址的處理程序.若是部署程序的服務器域名爲 www. example.com,在瀏覽器中訪問 http://www.example.com 後,會觸發服務器執行 index() 函 數.python
這個函數的返回值稱爲響應,是客戶端接收到的內容.若是客戶端是 Web 瀏覽器,響 應就是顯示給用戶查看的文檔.數據庫
也就是若是在「/」後添加各類自定義路徑就能夠實現返回本身定義的不一樣函數。flask
注意:在 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 類型也是字符串,但不把斜線視做分隔符,而將其看成動態片斷的一部分.
if __name__ == '__main__' app.run(debug=True)
app.run(host='0.0.0.0',port=80,debug=True)
爲了不大量無關緊要的參數把視圖函數弄得一團糟,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 在分發請求以前激活(或推送)程序和請求上下文,請求處理完成後再將其刪除.
程序上下文被推送後,就能夠在線程中使用 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() 可得到一個程序上 下文.
程序收到客戶端發來的請求時,要找處處理該請求的視圖函數.爲了完成這個任務,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 上時,會使用不一樣的視圖函數進行處理.
HEAD 和 OPTIONS 方法由 Flask 自動處理,所以能夠這麼說,在這個程序中,URL 映射中的 3 個路由都使用 GET 方法.
在請求鉤子函數和視圖函數之間共享數據通常使用上下文全局變量 g.例如,before_ request 處理程序能夠從數據庫中加載已登陸用戶,並將其保存到 g.user 中.隨後調用視 圖函數時,視圖函數再使用 g.user 獲取用戶.
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 服 務器
Flask 被設計爲可擴展形式,故而沒有提供一些重要的功能,例如數據庫和用戶認證,所 以開發者能夠自由選擇最適合程序的包,或者按需求自行開發.