Flask簡介
Flask是一個相對于Django而言輕量級的Web框架岂贩。
和Django大包大攬不同,F(xiàn)lask建立于一系列的開源軟件包之上抹镊,這其中 最主要的是WSGI應(yīng)用開發(fā)庫Werkzeug和模板引擎Jinja:
策略 :werkzeug和Jinja這兩個庫和Flask一樣垮耳,都是pocoo團隊開發(fā)的终佛。這 或許體現(xiàn)了pocoo與Django競爭時關(guān)于生態(tài)的一種策略铃彰,這種策略的自然 延伸是Flask框架中沒有包含數(shù)據(jù)庫方面的構(gòu)件豌研,無論ORM還是其他鹃共。
關(guān)注點 :Flask是一個WSGI應(yīng)用框架霜浴,這意味著我們進(jìn)行Flask開發(fā)時阴孟,不需要 關(guān)注網(wǎng)絡(luò)方面的操作永丝,F(xiàn)lask應(yīng)用的入口是封裝過的網(wǎng)絡(luò)請求包慕嚷,出口是 網(wǎng)絡(luò)響應(yīng)喝检,我們僅需要關(guān)注這個階段內(nèi)的處理邏輯挠说。
WSGI服務(wù)器 :Flask雖然內(nèi)置了簡單的WSGI服務(wù)器损俭,但其性能僅僅適用于開發(fā)期的調(diào)試撩炊。 Flask官網(wǎng)推薦了多種WSGI服務(wù)器拧咳,實現(xiàn)方式從多進(jìn)程到多線程到協(xié)程骆膝, 這方面的選擇我們在本課程中將不涉及阅签。
REST適應(yīng)性 :雖然Flask和Django一樣政钟,最初的出發(fā)點都是服務(wù)端的動態(tài)網(wǎng)頁應(yīng)用养交。但 Flask的設(shè)計使之也相當(dāng)適用于面向資源的REST架構(gòu)碎连,在越來越移動化 并且單頁應(yīng)用越來越重要的WEB開發(fā)領(lǐng)域鱼辙,這是Flask相對于Django相當(dāng) 大的優(yōu)勢倒戏。
Hello Flask
編寫一個基于Flask的hello world相當(dāng)容易:
1杜跷、導(dǎo)入Flask類
from flask import Flask
Flask類是Flask框架的核心類葱椭,它實現(xiàn)了WSGI應(yīng)用規(guī)范孵运。
2治笨、創(chuàng)建Flask實例
app = Flask(__name__)
Flask構(gòu)造函數(shù)的第一個參數(shù)指定一個引入名/import_name。Flask框架 使用這個名字進(jìn)行靜態(tài)資源顺又、模板、錯誤信息的定位果录。除非你清楚的理解它的 作用,通常情況下棋恼,我們總應(yīng)該使用特殊變量name义起。
Flask實例是可調(diào)用的(具有call方法),這個實例可以直接對接 WSGI服務(wù)器穷蛹。
3肴熏、注冊路由
@route('/')
def index():
return 'Hello,Flask!'
注冊路由就是建立URL規(guī)則和處理函數(shù)之間的關(guān)聯(lián)蛙吏。Flask框架依賴于路由 完成HTTP請求的分發(fā)鸦做。
路由中的函數(shù)被稱為視圖函數(shù)泼诱,其返回值將作為HTTP響應(yīng)的正文內(nèi)容治筒。
4耸袜、對接并啟動WSGI服務(wù)器
Flask封裝了一個簡單的開發(fā)用WSGI服務(wù)器堤框,我們可以通過調(diào)用run() 啟動服務(wù)器運行:
app.run(host='0.0.0.0',port=80)
概述
路由是MVC架構(gòu)的Web框架中相當(dāng)重要的一個概念胰锌,也是本節(jié)課程的重點资昧。
顧名思意格带,路由就是在迷茫中找出一條路的意思叽唱。在Flask框架中棺亭,路由就表示為用戶請求的URL找出其對應(yīng)的處理函數(shù)之意镶摘。
在本節(jié)課程凄敢,我們將主要從以下幾個方面講解Flask框架中的路由:
如何為應(yīng)用注冊路由涝缝? 如何為路由指定其支持的HTTP方法拒逮? 如何匹配動態(tài)URL滩援? 如何對URL中的變量類型進(jìn)行過濾? 如何理解訪問點/endpoint以现? 如何為應(yīng)用設(shè)定靜態(tài)路由? 如何避免硬編碼指向其他視圖的URL恰矩?
注冊路由
在Flask應(yīng)用中外傅,路由是指用戶請求的URL與視圖函數(shù)之間的映射俩檬。Flask框架 根據(jù)HTTP請求的URL在路由表中匹配預(yù)定義的URL規(guī)則棚辽,找到對應(yīng)的視圖函數(shù), 并將視圖函數(shù)的執(zhí)行結(jié)果返回WSGI服務(wù)器:
可見路由表在Flask應(yīng)用中處于相當(dāng)核心的位置。路由表的內(nèi)容是由應(yīng)用開發(fā)者填充搓扯。
route裝飾器 :可以使用Flask應(yīng)用實例的route裝飾器將一個URL規(guī)則綁定到 一個視圖函數(shù)上锨推。
例如公壤,下面的示例將URL規(guī)則/test綁定到視圖函數(shù)test()上:
@app.route('/test')
def test():
return 'this is response'
如果這個應(yīng)用部署在主機ezhost.com的根目錄下境钟,那么當(dāng)用戶訪問:
http://ezhost.com/test
Flask框架就會調(diào)用我們的test()函數(shù)洞渔,其返回結(jié)果就傳遞給WSGI服務(wù)器發(fā)送給訪問者。
add_url_rule() :另一種等價的寫法是使用Flask應(yīng)用實例的add_url_route()方法浆熔。 下面的示例注冊了一個與前例相同的路由:
def test():
return 'this is response'
app.add_url_route('/test',view_func=test)
其實慎皱,route裝飾器內(nèi)部也是通過調(diào)用add_url_route()方法實現(xiàn)的路由注冊忽刽。 但是顯然,使用裝飾器使代碼看起來更優(yōu)雅一些伞剑。
為路由指定HTTP方法
默認(rèn)情況下,F(xiàn)lask路由僅支持HTTP的GET請求『獗悖可以使用methods關(guān)鍵字參數(shù),在注冊 路由時顯式地聲明視圖方法支持的HTTP方法呆抑。
例如食绿,下面的示例將URL規(guī)則/auth綁定到視圖函數(shù)v_auth(),這個路由僅支持POST方法:
@app.route('/auth',methods=['POST'])
def v_auth():pass
指定多種HTTP方法支持
關(guān)鍵字參數(shù)methods的類型為list熊尉,因此可以同時指定多種HTTP方法硝清。
下面的示例中,使URL規(guī)則/user同時支持POST方法和GET方法:
@app.route('/user',methods=['POST','GET'])
def v_users():
if request.method == 'GET':
return ... # 返回用戶列表
if request.method == 'POST'
return ... #創(chuàng)建新用戶
這個特性使Flask非常易于開發(fā)REST架構(gòu)的后臺服務(wù),而不僅僅局限于傳統(tǒng)的動態(tài)網(wǎng)頁。
匹配動態(tài)URL
有時我們需要將同一類URL映射到同一個視圖函數(shù)處理,比如冬耿,使用同一個視圖函數(shù) 來顯示不同用戶的個人檔案。我們希望以下的URL都可以分發(fā)到同一個視圖函數(shù):
在Flask中,可以將URL中的可變部分使用一對小括號<>聲明為變量, 并為視圖函數(shù)聲明同名的參數(shù):
@app.route('/user/<uname>')
def v_user(uname):
return '%s\'s Profile' % uname
</uname>
在上面的示例中虱歪,URL規(guī)則中的<uname>表示這部分是可變的,F(xiàn)lask將提取用戶請求的 URL中這部分的內(nèi)容,并作為視圖函數(shù)v_user()的uname參數(shù)進(jìn)行調(diào)用拨脉。
URL變量類型過濾
考慮下面的示例,我們希望通過HTTP共享文件夾/var/readonly中的文件:
/var
/readonly
/a.txt
/b.txt
/repo
/c.txt
/d.txt
簡單思考一下就有答案了。我們可以構(gòu)造URL規(guī)則/file/<fname>解阅,然后直接 讀取文件內(nèi)容返回給用戶朱转。注冊如下的路由:
@app.route('/file/<fname>')
def v_file(fname):
fullname = os.path.join('/var/readonly',fname)
f = open(fullname)
cnt = f.read()
f.close()
return cnt
</fname>
測試結(jié)果表明,/file/a.txt和/file/b.txt都沒有問題,但是/file/repo/c.txt和 /file/repo/d.txt卻會失敗。
這是因為,默認(rèn)情況下,在URL規(guī)則中的變量被視為不包含/的字符串羞海。/file/repo/c.txt 是沒有辦法匹配URL規(guī)則/file/<fname>的。
可以使用內(nèi)置的path轉(zhuǎn)換器告訴Flask框架改變這一默認(rèn)行為。path轉(zhuǎn)換器允許 規(guī)則匹配包含/的字符串:
@app.route('/file/<path:fname>')
</path:fname>
在Flask中恢恼,轉(zhuǎn)換器/converter用來對從URL中提取的變量進(jìn)行預(yù)處理牵署,這個過程 發(fā)生在調(diào)用視圖函數(shù)之前锁保。Flask預(yù)置了四種轉(zhuǎn)換器:
string - 匹配不包含/的字符串,這是默認(rèn)的轉(zhuǎn)換器
path - 匹配包含/的字符串
int - 只有當(dāng)URL中的變量是整型值時才匹配,并將變量轉(zhuǎn)換為整型
float - 只有當(dāng)URL中的變量是浮點值時才匹配心墅,并將變量轉(zhuǎn)換為浮點型
訪問點/endpoint
我們一直強調(diào)蜜暑,路由的作用是根據(jù)請求的URL,找到對應(yīng)的視圖函數(shù)隐绵。這沒錯依许,但是在 Flask框架中峭跳,請求任務(wù)的分發(fā)并不是直接從用戶請求的URL一步定位到視圖函數(shù), 兩者之間隔著一個訪問點/endpoint竣付。
以下面的代碼為例滞欠,我們看Flask怎樣實現(xiàn)請求的分發(fā):
@app.route('/home')
def home():pass
在Flask內(nèi)部使用兩張表維護路由:
url_map :維護URL規(guī)則和endpoint的映射
view_functions :維護endpoint和視圖函數(shù)的映射筛璧。
以用戶訪問URL/home為例,F(xiàn)lask將首先利用url_map找到所請求URL對應(yīng)的 endpoint棺牧,即訪問點home颊乘,然后再利用view_functions表查找home這個訪問點 對應(yīng)的視圖函數(shù),最終匹配到函數(shù)home():
默認(rèn)訪問點 :當(dāng)我們使用route裝飾器注冊路由時规求,默認(rèn)使用被裝飾函數(shù)的 函數(shù)名(name)作為訪問點蛹找,因此当编,你看到上面的表中渠概,路由中的訪問點為home。
自定義訪問點 :可以在使用route裝飾器或調(diào)用add_url_rule()方法注冊路由時,使用 endpoint關(guān)鍵字參數(shù)改變這一默認(rèn)行為:
@app.route('/home',endpoint='whocare')
def home():pass
此時的兩張路由表將變成這樣:
靜態(tài)目錄路由
當(dāng)創(chuàng)建應(yīng)用實例時峡继,F(xiàn)lask將自動添加一條靜態(tài)目錄路由择膝,其訪問點 始終被設(shè)置為static,URL規(guī)則默認(rèn)被設(shè)置為/static复濒,本地路徑默認(rèn)被 設(shè)置為應(yīng)用文件夾下的static子文件夾:
+------------------------------------------------------------+ | url rule | endpoint | view_function | | /static | static | Flask.send_static_file | +------------------------------------------------------------+ 如果你的應(yīng)用目錄如下:
/app
/web.py
/static
/main.css
/jquery.min.js
那么啟動應(yīng)用后就可以通過URL/static/main.css訪問static文件夾下的main.css了攻锰。
除了訪問點被固定為static机断,靜態(tài)目錄的URL規(guī)則和本地目錄都是可以根據(jù)應(yīng)用情況進(jìn)行調(diào)整。
改變默認(rèn)的本地路徑 :可以在創(chuàng)建應(yīng)用對象時使用關(guān)鍵字參數(shù)static_folder改變 默認(rèn)的靜態(tài)文件夾。例如酗钞,你的靜態(tài)文件都存放在應(yīng)用下的assets目錄下蔼夜, 那么可以按如下的方式創(chuàng)建應(yīng)用對象:
app = Flask(name,static_folder='assets') 也可以使用一個絕對路徑:
app = Flask(name,static_folder='/var/www/static') 改變默認(rèn)的本地路徑并不會對路由表產(chǎn)生影響但金。
改變默認(rèn)的URL規(guī)則 : 如果不喜歡靜態(tài)目錄URL/static,也可以在創(chuàng)建應(yīng)用 對象時使用關(guān)鍵字參數(shù)static_url_path換一個別的名字答憔。
下面的示例中蓉驹,將應(yīng)用下的assets文件夾注冊為靜態(tài)目錄/assets:
app = Flask(name,static_folder='assets',static_url_path='/assets') 當(dāng)應(yīng)用運行后工坊,通過URL/assets/main.css就可以訪問assets文件夾下的 main.css文件了阱驾。
這時的路由表變化為:
+------------------------------------------------------------+ | url | endpoint | view_function | | /assets | static | Flask.send_static_file | +------------------------------------------------------------+
構(gòu)造URL
如果對Python編程隧甚、網(wǎng)絡(luò)爬蟲宜雀、機器學(xué)習(xí)、數(shù)據(jù)挖掘退子、web開發(fā)、人工智能、面試經(jīng)驗交流。感興趣可以519970686,群內(nèi)會有不定期的發(fā)放免費的資料鏈接碰缔,這些資料都是從各個技術(shù)網(wǎng)站搜集禀晓、整理出來的,如果你有好的學(xué)習(xí)資料可以私聊發(fā)我,我會注明出處之后分享給大家菊匿。
在一個實用的視圖中,不可避免地存在指向其他視圖的鏈接钙姊。在之前的課程示例中壁袄,我們 都是在視圖函數(shù)中這樣硬編碼這些鏈接URL的:
@app.route('/')
def v_index():
return '<a href="/tech">tech</a>'
@app.route('/tech')
def v_tech():pass
大部分情況下這種硬編碼URL是可以工作的萄凤。但如果這個應(yīng)用被掛在WSGI服務(wù)器的一個 子路徑下,比如:/app1,那么用戶訪問URL/tech是不會成功的护奈,這時應(yīng)當(dāng)訪問/app1/tech 才可以正確地路由到視圖函數(shù)v_tech()擅憔。
我們應(yīng)當(dāng)使用訪問點讓Flask框架幫我們計算鏈接URL芥喇。簡單地給url_for()函數(shù)傳入 一個訪問點,它返回將是一個可靠的URL地址:
@app.route('/')
def v_index():
print url_for('v_contacts') # /contact
return 'see console output!'
@app.route('/contact')
def v_contacts():pass
添加查詢參數(shù) : 使用關(guān)鍵字參數(shù)错沽,可以在構(gòu)造的URL中生成查詢串。下面的調(diào)用將生成 /contact?format=json
@app.route('/')
def v_index():
print url_for('v_contacts',format='json')
return ''
@app.route('/contact')
def v_contacts():pass
添加URL變量 : 如果指定訪問點對應(yīng)的視圖函數(shù)接收參數(shù)翰守,那么關(guān)鍵字參數(shù)將生成對應(yīng)的參數(shù)URL劝堪。下面的 示例將生成/contact/Julia?format=html:
@app.route('/')
def v_index():
print url_for('v_contact',name='Julia',format='html')
return ''
@app.route('/contact/<name>')
def v_contact(name):pass
</name>
添加錨點 :使用_anchor關(guān)鍵字可以為生成的URL添加錨點含末。下面的示例將生成URL /contact#part2
@app.route('/')
def v_index():
print url_for('v_contacts',_anchor='part2')
@app.route('/contact')
def v_contacts():pass
外部URL : 默認(rèn)情況下,url_for()生成站內(nèi)URL全景,可以設(shè)置關(guān)鍵字參數(shù)_external 為True,生成包含站點地址的外部URL。下面的示例將生成URLhttp://<x.y.z>/contacts:
@app.route('/')
def v_index():
print url_for('v_contacts',_external=True)
@app.route('/contact')
def v_contacts():pass
作者:拿Q
來源:CSDN
原文:https://blog.csdn.net/Stephen_shijun/article/details/83346173
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接菱肖!