python flask框架詳解
Flask是一個(gè)Python編寫(xiě)的Web 微框架,讓我們可以使用Python語(yǔ)言快速實(shí)現(xiàn)一個(gè)網(wǎng)站或Web服務(wù)。本文參考自Flask官方文檔,英文不好的同學(xué)也可以參考中文文檔
1.安裝flaskpip install flask2.簡(jiǎn)單上手
一個(gè)最小的 Flask 應(yīng)用如下:
from flask import Flaskapp = Flask(__name__)@app.route(’/’)def hello_world(): return ’Hello World’if __name__ == ’__main__’: app.run()
代碼解析:1、首先我們導(dǎo)入了 Flask 類(lèi)。 該類(lèi)的實(shí)例將會(huì)成為我們的 WSGI 應(yīng)用。2、接著我們創(chuàng)建一個(gè)該類(lèi)的實(shí)例。第一個(gè)參數(shù)是應(yīng)用模塊或者包的名稱。如果你使用 一個(gè)單一模塊(就像本例),那么應(yīng)當(dāng)使用 name ,因?yàn)槊Q會(huì)根據(jù)這個(gè) 模塊是按應(yīng)用方式使用還是作為一個(gè)模塊導(dǎo)入而發(fā)生變化(可能是 ‘main’ , 也可能是實(shí)際導(dǎo)入的名稱)。這個(gè)參數(shù)是必需的,這樣 Flask 才能知道在哪里可以 找到模板和靜態(tài)文件等東西3、然后我們使用 route() 裝飾器來(lái)告訴 Flask 觸發(fā)函數(shù)的 URL 。4、函數(shù)名稱被用于生成相關(guān)聯(lián)的 URL 。函數(shù)最后返回需要在用戶瀏覽器中顯示的信息。
運(yùn)行結(jié)果:
* Serving Flask app 'flask_demo' (lazy loading)* Environment: productionWARNING: This is a development server. Do not use it in a production deployment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
訪問(wèn):http://127.0.0.1:5000/
app.route(rule, options) rule 參數(shù)表示與該函數(shù)的URL綁定。 options 是要轉(zhuǎn)發(fā)給基礎(chǔ)Rule對(duì)象的參數(shù)列表。在上面的示例中,’/ ’ URL與hello_world()函數(shù)綁定。因此,當(dāng)在瀏覽器中打開(kāi)web服務(wù)器的主頁(yè)時(shí),將呈現(xiàn)該函數(shù)的輸出。最后,F(xiàn)lask類(lèi)的run()方法在本地開(kāi)發(fā)服務(wù)器上運(yùn)行應(yīng)用程序。
app.run(host, port, debug, options)
所有參數(shù)都是可選的
host:要監(jiān)聽(tīng)的主機(jī)名。 默認(rèn)為127.0.0.1(localhost)。設(shè)置為“0.0.0.0”以使服務(wù)器在外部可用 port :默認(rèn)值為5000 debug:默認(rèn)為false。 如果設(shè)置為true,則提供調(diào)試信息,可以自動(dòng)重載代碼并顯示調(diào)試信息 options:要轉(zhuǎn)發(fā)到底層的Werkzeug服務(wù)器。2.1 調(diào)試模式雖然 flask 命令可以方便地啟動(dòng)一個(gè)本地開(kāi)發(fā)服務(wù)器,但是每次應(yīng)用代碼 修改之后都需要手動(dòng)重啟服務(wù)器。這樣不是很方便, Flask 可以做得更好。如果你打開(kāi) 調(diào)試模式,那么服務(wù)器會(huì)在修改應(yīng)用代碼之后自動(dòng)重啟,并且當(dāng)應(yīng)用出錯(cuò)時(shí)還會(huì)提供一個(gè) 有用的調(diào)試器。在命令行中,如果需要打開(kāi)所有開(kāi)發(fā)功能(包括調(diào)試模式),那么要在運(yùn)行服務(wù)器之前導(dǎo)出 FLASK_ENV 環(huán)境變量并把其設(shè)置為 development:
$ export FLASK_ENV=development$ flask run
在代碼中,在運(yùn)行或?qū)⒄{(diào)試參數(shù)傳遞給run()方法之前,通過(guò)將application對(duì)象的debug屬性設(shè)置為T(mén)rue來(lái)啟用Debug模式。
app.debug = Trueapp.run()# 或者app.run(debug = True)2.2 綁定IP和端口
默認(rèn)情況下,F(xiàn)lask綁定IP為127.0.0.1,端口為5000。我們也可以通過(guò)下面的方式自定義:
app.run(host=’0.0.0.0’, port=80, debug=True)
0.0.0.0代表電腦所有的IP。80是HTTP網(wǎng)站服務(wù)的默認(rèn)端口。什么是默認(rèn)?比如,我們?cè)L問(wèn)網(wǎng)站http://www.example.com,其實(shí)是訪問(wèn)的http://www.example.com:80,只不過(guò):80可以省略不寫(xiě)。
3.Flask 路由現(xiàn)代Web框架使用路由技術(shù)來(lái)幫助用戶記住應(yīng)用程序URL。可以直接訪問(wèn)所需的頁(yè)面,而無(wú)需從主頁(yè)導(dǎo)航。
Flask中的route()裝飾器用于將URL綁定到函數(shù)。例如:
@app.route(’/hello’)def hello_world(): return ’hello world’
在這里,URL’/ hello’規(guī)則綁定到hello_world()函數(shù)。 因此,如果用戶訪問(wèn)http://localhost:5000/hello URL,hello_world()函數(shù)的輸出將在瀏覽器中呈現(xiàn)。
application對(duì)象的add_url_rule()函數(shù)也可用于將URL與函數(shù)綁定,如上例所示,使用route()裝飾器的目的也由以下表示:
def hello_world(): return ’hello world’app.add_url_rule(’/’, ’hello’, hello_world)4.Flask 變量規(guī)則
通過(guò)向規(guī)則參數(shù)添加變量部分,可以動(dòng)態(tài)構(gòu)建URL。此變量部分標(biāo)記為 <converter:variable_name>。它作為關(guān)鍵字參數(shù)傳遞給與規(guī)則相關(guān)聯(lián)的函數(shù)。在以下示例中,route()裝飾器的規(guī)則參數(shù)包含附加到URL’/hello’的<name>。 因此,如果在瀏覽器中輸入http://localhost:5000/hello/chenshifeng作為URL,則’chenshifeng’將作為參數(shù)提供給 hello()函數(shù)。
#!/usr/bin/python# -*- coding: UTF-8 -*-'''@author:chenshifeng@file:flask_demo.py@time:2021/03/01'''from flask import Flaskapp = Flask(__name__)@app.route(’/hello/<name>’)def hello_name(name): return ’Hello %s!’ % nameif __name__ == ’__main__’: app.run(debug=True)
運(yùn)行,訪問(wèn):http://localhost:5000/hello/chenshifeng
除了默認(rèn)字符串變量部分之外,還可以使用以下轉(zhuǎn)換器構(gòu)建規(guī)則:
轉(zhuǎn)換器 描述 string (缺省值) 接受任何不包含斜杠的文本 int 接受正整數(shù) float 接受正浮點(diǎn)數(shù) path 類(lèi)似 string ,但可以包含斜杠 uuid 接受 UUID 字符串
#!/usr/bin/python# -*- coding: UTF-8 -*-'''@author:chenshifeng@file:flask_demo.py@time:2021/03/01'''from flask import Flaskapp = Flask(__name__)@app.route(’/post/<int:post_id>’)def show_post(post_id): # show the post with the given id, the id is an integer return ’Post %d’ % [email protected](’/path/<path:subpath>’)def show_subpath(subpath): # show the subpath after /path/ return ’Subpath %s’ % subpathif __name__ == ’__main__’: app.run(debug=True)
以下兩條規(guī)則的不同之處在于是否使用尾部的斜杠。:
@app.route(’/projects/’)def projects(): return ’The project page’@app.route(’/about’)def about(): return ’The about page’
projects 的 URL 是中規(guī)中矩的,尾部有一個(gè)斜杠,看起來(lái)就如同一個(gè)文件夾。 訪問(wèn)一個(gè)沒(méi)有斜杠結(jié)尾的 URL 時(shí) Flask 會(huì)自動(dòng)進(jìn)行重定向,幫你在尾部加上一個(gè)斜杠。
about 的 URL 沒(méi)有尾部斜杠,因此其行為表現(xiàn)與一個(gè)文件類(lèi)似。如果訪問(wèn)這個(gè) URL 時(shí)添加了尾部斜杠就會(huì)得到一個(gè) 404 錯(cuò)誤。這樣可以保持 URL 唯一,并幫助 搜索引擎避免重復(fù)索引同一頁(yè)面。
5.Flask URL構(gòu)建url_for()函數(shù)對(duì)于動(dòng)態(tài)構(gòu)建特定函數(shù)的URL非常有用。該函數(shù)接受函數(shù)的名稱作為第一個(gè)參數(shù),以及一個(gè)或多個(gè)關(guān)鍵字參數(shù),每個(gè)參數(shù)對(duì)應(yīng)于URL的變量部分。
#!/usr/bin/python# -*- coding: UTF-8 -*-'''@author:chenshifeng@file:flask_demo.py@time:2021/03/01'''from flask import Flask, redirect, url_forapp = Flask(__name__)@app.route(’/admin’)def hello_admin(): return ’Hello Admin’@app.route(’/guest/<guest>’)def hello_guest(guest): return ’Hello %s as Guest’ % [email protected](’/user/<name>’)def hello_user(name): if name == ’admin’: return redirect(url_for(’hello_admin’)) else: return redirect(url_for(’hello_guest’, guest=name))if __name__ == ’__main__’: app.run(debug=True)
redirect函數(shù)用于重定向,實(shí)現(xiàn)機(jī)制很簡(jiǎn)單,就是向客戶端(瀏覽器)發(fā)送一個(gè)重定向的HTTP報(bào)文,瀏覽器會(huì)去訪問(wèn)報(bào)文中指定的url。
運(yùn)行打開(kāi)瀏覽器并輸入U(xiǎn)RL - http://localhost:5000/user/admin
Hello Admin
在瀏覽器中輸入以下URL - http://localhost:5000/user/mvl
Hello mvl as Guest
6.Flask HTTP方法Web 應(yīng)用使用不同的 HTTP 方法處理 URL 。當(dāng)你使用 Flask 時(shí),應(yīng)當(dāng)熟悉 HTTP 方法。 缺省情況下,一個(gè)路由只回應(yīng) GET 請(qǐng)求。 可以使用 route() 裝飾器的 methods 參數(shù)來(lái)處理不同的 HTTP 方法:
方法 描述 GET 以未加密的形式將數(shù)據(jù)發(fā)送到服務(wù)器,最常見(jiàn)的方法。 HEAD 和GET方法相同,但沒(méi)有響應(yīng)體。 POST 用于將HTML表單數(shù)據(jù)發(fā)送到服務(wù)器,POST方法接收的數(shù)據(jù)不由服務(wù)器緩存。 PUT 用上傳的內(nèi)容替換目標(biāo)資源的所有當(dāng)前表示。 DELETE 刪除由URL給出的目標(biāo)資源的所有當(dāng)前表示。
默認(rèn)情況下,F(xiàn)lask路由響應(yīng)GET請(qǐng)求。但是,可以通過(guò)為route()裝飾器提供方法參數(shù)來(lái)更改此首選項(xiàng)。
為了演示在URL路由中使用POST方法,首先讓我們創(chuàng)建一個(gè)HTML表單,并使用POST方法將表單數(shù)據(jù)發(fā)送到URL。將以下腳本另存為login.html
<html> <body> <form action = 'http://localhost:5000/login' method = 'post'> <p>Enter Name:</p> <p><input type = 'text' name = 'nm' /></p> <p><input type = 'submit' value = 'submit' /></p> </form> </body></html>
運(yùn)行以下代碼
from flask import Flask, redirect, url_for, requestapp = Flask(__name__)@app.route(’/success/<name>’)def success(name): return ’welcome %s’ % [email protected](’/login’,methods = [’POST’, ’GET’])def login(): if request.method == ’POST’: user = request.form[’nm’] return redirect(url_for(’success’,name = user)) else: user = request.args.get(’nm’) return redirect(url_for(’success’,name = user))if __name__ == ’__main__’: app.run(debug = True)
在瀏覽器中打開(kāi)login.html,在文本字段中輸入name,然后單擊提交。
表單數(shù)據(jù)將POST到表單標(biāo)簽的action子句中的URL。
http://localhost/login映射到login()函數(shù)。由于服務(wù)器通過(guò)POST方法接收數(shù)據(jù),因此通過(guò)以下步驟獲得從表單數(shù)據(jù)獲得的“nm”參數(shù)的值:表單數(shù)據(jù)將POST到表單標(biāo)簽的action子句中的URL。
user = request.form[’nm’]
它作為變量部分傳遞給’/ success’ URL。瀏覽器在窗口中顯示welcome消息。
在login.html中將方法參數(shù)更改為’GET’,然后在瀏覽器中再次打開(kāi)它。服務(wù)器上接收的數(shù)據(jù)是通過(guò)GET方法獲得的。通過(guò)以下的步驟獲得’nm’參數(shù)的值:
User = request.args.get(’nm’)
這里,args是包含表單參數(shù)對(duì)及其對(duì)應(yīng)值對(duì)的列表的字典對(duì)象。與’nm’參數(shù)對(duì)應(yīng)的值將像之前一樣傳遞到’/ success’ URL。
7.Flask 模板在大型應(yīng)用中,把業(yè)務(wù)邏輯和表現(xiàn)內(nèi)容放在一起,會(huì)增加代碼的復(fù)雜度和維護(hù)成本.
模板其實(shí)是一個(gè)包含響應(yīng)文本的文件,其中用占位符(變量)表示動(dòng)態(tài)部分,告訴模板引擎其具體的值需要從使用的數(shù)據(jù)中獲取 使用真實(shí)值替換變量,再返回最終得到的字符串,這個(gè)過(guò)程稱為’渲染’ Flask 是使用 Jinja2 這個(gè)模板引擎來(lái)渲染模板使用模板的好處
視圖函數(shù)只負(fù)責(zé)業(yè)務(wù)邏輯和數(shù)據(jù)處理(業(yè)務(wù)邏輯方面)而模板則取到視圖函數(shù)的數(shù)據(jù)結(jié)果進(jìn)行展示(視圖展示方面)代碼結(jié)構(gòu)清晰,耦合度低
使用 render_template() 方法可以渲染模板,你只要提供模板名稱和需要 作為參數(shù)傳遞給模板的變量就行了。Flask 會(huì)在 templates 文件夾內(nèi)尋找模板。因此,如果你的應(yīng)用是一個(gè)模塊, 那么模板文件夾應(yīng)該在模塊旁邊;如果是一個(gè)包,那么就應(yīng)該在包里面:情形 1 : 一個(gè)模塊:
/application.py/templates /hello.html
情形 2 : 一個(gè)包:
/application /__init__.py /templates /hello.html
示例代碼:
from flask import Flask, render_templateapp = Flask(__name__)@app.route(’/’)def index(): my_int = 18 my_str = ’curry’ my_list = [1, 5, 4, 3, 2] my_dict = { ’name’: ’durant’, ’age’: 28 } # render_template方法:渲染模板 # 參數(shù)1: 模板名稱 參數(shù)n: 傳到模板里的數(shù)據(jù) return render_template(’hello.html’, my_int=my_int, my_str=my_str, my_list=my_list, my_dict=my_dict)if __name__ == ’__main__’: app.run(debug=True)
<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>Title</title></head><body> <h2>我是模板</h2> {{ my_int }} <br> {{ my_str }} <br> {{ my_list }} <br> {{ my_dict }} <hr> <h2>模板的list數(shù)據(jù)獲取</h2> <hr> {{ my_list[0] }} <br> {{ my_list.1 }} <hr> <h2>字典數(shù)據(jù)獲取</h2> <hr> {{ my_dict[’name’] }} <br> {{ my_dict.age }} <hr> <h2>算術(shù)運(yùn)算</h2> <br> {{ my_list.0 + 10 }} <br> {{ my_list[0] + my_list.1 }}</body></html>
運(yùn)行效果:
動(dòng)態(tài)的 web 應(yīng)用也需要靜態(tài)文件,一般是 CSS 和 JavaScript 文件。理想情況下你的 服務(wù)器已經(jīng)配置好了為你的提供靜態(tài)文件的服務(wù)。但是在開(kāi)發(fā)過(guò)程中, Flask 也能做好 這項(xiàng)工作。只要在你的包或模塊旁邊創(chuàng)建一個(gè)名為 static 的文件夾就行了。 靜態(tài)文件位于應(yīng)用的 /static 中。使用特定的 ’static’ 端點(diǎn)就可以生成相應(yīng)的 URL
url_for(’static’, filename=’style.css’)
這個(gè)靜態(tài)文件在文件系統(tǒng)中的位置應(yīng)該是 static/style.css 。
在下面的示例中,在index.html中的HTML按鈕的OnClick事件上調(diào)用hello.js中定義的javascript函數(shù),該函數(shù)在Flask應(yīng)用程序的“/”URL上呈現(xiàn)。
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/')def index(): return render_template('index.html')if __name__ == ’__main__’: app.run(debug = True)
index.html的HTML腳本如下所示:
<html> <head> <script type = 'text/javascript' src = 'http://www.aoyou183.cn/bcjs/{{ url_for(’static’, filename = ’hello.js’) }}' ></script> </head> <body> <input type = 'button' onclick = 'sayHello()' value = 'Say Hello' /> </body></html>
Hello.js包含sayHello()函數(shù)。
function sayHello() { alert('Hello World')}
運(yùn)行效果:
來(lái)自客戶端網(wǎng)頁(yè)的數(shù)據(jù)作為全局請(qǐng)求對(duì)象發(fā)送到服務(wù)器。為了處理請(qǐng)求數(shù)據(jù),應(yīng)該從Flask模塊導(dǎo)入。
Request對(duì)象的重要屬性如下所列:
form - 它是一個(gè)字典對(duì)象,包含表單參數(shù)及其值的鍵和值對(duì)。 args - 解析查詢字符串的內(nèi)容,它是問(wèn)號(hào)(?)之后的URL的一部分。 Cookies - 保存Cookie名稱和值的字典對(duì)象。 files - 與上傳文件有關(guān)的數(shù)據(jù)。 method - 當(dāng)前請(qǐng)求方法首先,你必須從 flask 模塊導(dǎo)入請(qǐng)求對(duì)象:
from flask import request9.1 Flask 將表單數(shù)據(jù)發(fā)送到模板
我們已經(jīng)看到,可以在 URL 規(guī)則中指定 http 方法。觸發(fā)函數(shù)接收的 Form 數(shù)據(jù)可以以字典對(duì)象的形式收集它并將其轉(zhuǎn)發(fā)到模板以在相應(yīng)的網(wǎng)頁(yè)上呈現(xiàn)它。
在以下示例中,’/’ URL 會(huì)呈現(xiàn)具有表單的網(wǎng)頁(yè)(student.html)。填入的數(shù)據(jù)會(huì)發(fā)布到觸發(fā) result() 函數(shù)的 ’/result’ URL。
result() 函數(shù)收集字典對(duì)象中的 request.form 中存在的表單數(shù)據(jù),并將其發(fā)送給 result.html。
該模板動(dòng)態(tài)呈現(xiàn)表單數(shù)據(jù)的 HTML 表格。
下面給出的是應(yīng)用程序的 Python 代碼:
from flask import Flask, render_template, requestapp = Flask(__name__)@app.route(’/’)def student(): return render_template(’student.html’)@app.route(’/result’,methods = [’POST’, ’GET’])def result(): if request.method == ’POST’: result = request.form return render_template('result.html',result = result)if __name__ == ’__main__’: app.run(debug = True)
下面給出的是 student.html 的 HTML 腳本。
<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>Title</title></head><body> <form action='http://localhost:5000/result' method='POST'> <p>Name <input type = 'text' name = 'Name' /></p> <p>Physics <input type = 'text' name = 'Physics' /></p> <p>Chemistry <input type = 'text' name = 'chemistry' /></p> <p>Maths <input type ='text' name = 'Mathematics' /></p> <p><input type = 'submit' value = 'submit' /></p> </form></body></html>
下面給出了模板( result.html )的代碼:
<!doctype html> <table border = 1> {% for key, value in result.items() %} <tr> <th> {{ key }} </th> <td> {{ value }}</td> </tr> {% endfor %}</table>
運(yùn)行效果:運(yùn)行 Python 腳本,并在瀏覽器中輸入 URL http://localhost:5000/。
當(dāng)點(diǎn)擊提交按鈕時(shí),表單數(shù)據(jù)以 HTML 表格的形式呈現(xiàn)在 result.html 上。
Cookie以文本文件的形式存儲(chǔ)在客戶端的計(jì)算機(jī)上。其目的是記住和跟蹤與客戶使用相關(guān)的數(shù)據(jù),以獲得更好的訪問(wèn)者體驗(yàn)和網(wǎng)站統(tǒng)計(jì)信息。
Request對(duì)象包含Cookie的屬性。它是所有cookie變量及其對(duì)應(yīng)值的字典對(duì)象,客戶端已傳輸。除此之外,cookie還存儲(chǔ)其網(wǎng)站的到期時(shí)間,路徑和域名。在Flask中,對(duì)cookie的處理步驟為:
1.設(shè)置cookie:設(shè)置cookie,默認(rèn)有效期是臨時(shí)cookie,瀏覽器關(guān)閉就失效可以通過(guò) max_age 設(shè)置有效期, 單位是秒
cookie_1 = request.cookies.get('chenshifeng')
2.獲取cookie獲取cookie,通過(guò)request.cookies的方式, 返回的是一個(gè)字典,可以獲取字典里的相應(yīng)的值
resp = make_response('del success') # 設(shè)置響應(yīng)體resp.delete_cookie('chenshifeng')
3.刪除cookie這里的刪除只是讓cookie過(guò)期,并不是直接刪除cookie刪除cookie,通過(guò)delete_cookie()的方式, 里面是cookie的名字
resp = make_response('del success') # 設(shè)置響應(yīng)體resp.delete_cookie('chenshifeng')
以下為Flask Cookies的簡(jiǎn)單示例:
from flask import Flask, make_response, requestapp = Flask(__name__)@app.route('/set_cookies')def set_cookie(): resp = make_response('success') resp.set_cookie('chenshifeng', 'shifengboy',max_age=3600) return [email protected]('/get_cookies')def get_cookie(): cookie_1 = request.cookies.get('chenshifeng') # 獲取名字為Itcast_1對(duì)應(yīng)cookie的值 return [email protected]('/delete_cookies')def delete_cookie(): resp = make_response('del success') resp.delete_cookie('chenshifeng') return respif __name__ == ’__main__’: app.run(debug=True)
設(shè)置cookies
運(yùn)行應(yīng)用程序,在瀏覽器中輸入 127.0.0.1:5000/set_cookies 來(lái)設(shè)置cookies,設(shè)置 cookies 的輸出如下所示:
獲取cookie
根據(jù)視圖函數(shù)中相對(duì)應(yīng)的路徑,輸入 http://127.0.0.1:5000/get_cookies ,讀回 cookies 的輸出如下所示:
刪除cookie
根據(jù)視圖函數(shù)中相對(duì)應(yīng)的路徑,輸入 http://127.0.0.1:5000/delete_cookies ,刪除 cookies 的輸出如下所示:
注意刪除,只是讓 cookie 過(guò)期。
10.Flask 會(huì)話與Cookie不同,Session(會(huì)話)數(shù)據(jù)存儲(chǔ)在服務(wù)器上。會(huì)話是客戶端登錄到服務(wù)器并注銷(xiāo)服務(wù)器的時(shí)間間隔。需要在該會(huì)話中保存的數(shù)據(jù)會(huì)存儲(chǔ)在服務(wù)器上的臨時(shí)目錄中。
為每個(gè)客戶端的會(huì)話分配會(huì)話ID。會(huì)話數(shù)據(jù)存儲(chǔ)在cookie的頂部,服務(wù)器以加密方式對(duì)其進(jìn)行簽名。對(duì)于此加密,F(xiàn)lask應(yīng)用程序需要一個(gè)定義的SECRET_KEY。
Session對(duì)象也是一個(gè)字典對(duì)象,包含會(huì)話變量和關(guān)聯(lián)值的鍵值對(duì)。
例如,要設(shè)置一個(gè)’username’會(huì)話變量,請(qǐng)使用以下語(yǔ)句:
Session[’username’] = ’admin’
要釋放會(huì)話變量,請(qǐng)使用pop()方法。
session.pop(’username’, None)
演示代碼:
from flask import Flask, session, redirect, url_for, requestapp = Flask(__name__)app.secret_key = ’fkdjsafjdkfdlkjfadskjfadskljdsfklj’ # 確保設(shè)置應(yīng)用程序的[email protected](’/’)def index(): if ’username’ in session: username = session[’username’] return ’登錄用戶名是:’ + username + ’<br>’ + '<b><a href = ’/logout’>點(diǎn)擊這里注銷(xiāo)</a></b>' return '您暫未登錄, <br><a href = ’/login’></b>' + '點(diǎn)擊這里登錄</b></a>'@app.route(’/login’, methods=[’GET’, ’POST’])def login(): if request.method == ’POST’: session[’username’] = request.form[’username’] return redirect(url_for(’index’)) return ’’’ <form action = '' method = 'post'> <p><input type ='text' name ='username'/></p> <p><input type ='submit' value ='登錄'/></p> </form> ’’’@app.route(’/logout’)def logout(): # remove the username from the session if it is there session.pop(’username’, None) return redirect(url_for(’index’))if __name__ == ’__main__’: app.run(debug=True)
如何生成一個(gè)好的密鑰生成隨機(jī)數(shù)的關(guān)鍵在于一個(gè)好的隨機(jī)種子,因此一個(gè)好的密鑰應(yīng)當(dāng)有足夠的隨機(jī)性。 操作系統(tǒng)可以有多種方式基于密碼隨機(jī)生成器來(lái)生成隨機(jī)數(shù)據(jù)。使用下面的命令 可以快捷的為 Flask.secret_key ( 或者 SECRET_KEY )生成值:$ python -c ’import os; print(os.urandom(16))’b’_5#y2L'F4Q8znxec]/’
訪問(wèn)http://127.0.0.1:5000/,只是提示用戶登錄,因?yàn)槲丛O(shè)置會(huì)話變量’username’。
當(dāng)用戶點(diǎn)擊登錄,瀏覽到“/login”login()視圖函數(shù)時(shí),因?yàn)樗峭ㄟ^(guò)GET方法調(diào)用的,所以將打開(kāi)一個(gè)登錄表單。
點(diǎn)擊登錄,通過(guò)POST方法將表單發(fā)送回’/login’,現(xiàn)在會(huì)話變量已設(shè)置。應(yīng)用程序重定向到’/’。此時(shí)會(huì)話變量’username’被找到。
應(yīng)用程序還包含一個(gè)logout()視圖函數(shù),它會(huì)彈出’username’會(huì)話變量。因此,’/’ URL再次顯示開(kāi)始頁(yè)面。
Flask類(lèi)有一個(gè)redirect()函數(shù)。調(diào)用時(shí),它返回一個(gè)響應(yīng)對(duì)象,并將用戶重定向到具有指定狀態(tài)代碼的另一個(gè)目標(biāo)位置。
redirect()函數(shù)的原型如下:
Flask.redirect(location, statuscode, response)
在上述函數(shù)中:
location參數(shù)是應(yīng)該重定向響應(yīng)的URL。 statuscode發(fā)送到瀏覽器標(biāo)頭,默認(rèn)為302。 response參數(shù)用于實(shí)例化響應(yīng)。以下?tīng)顟B(tài)代碼已標(biāo)準(zhǔn)化:
HTTP_300_MULTIPLE_CHOICES HTTP_301_MOVED_PERMANENTLY HTTP_302_FOUND HTTP_303_SEE_OTHER HTTP_304_NOT_MODIFIED HTTP_305_USE_PROXY HTTP_306_RESERVED HTTP_307_TEMPORARY_REDIRECT默認(rèn)狀態(tài)代碼為302,表示’found’。在以下示例中,redirect()函數(shù)用于在登錄嘗試失敗時(shí)再次顯示登錄頁(yè)面。
from flask import Flask, redirect, url_for, render_template, request# Initialize the Flask applicationapp = Flask(__name__)@app.route(’/’)def index(): return render_template(’log_in.html’)@app.route(’/login’, methods=[’POST’, ’GET’])def login(): if request.method == ’POST’ and request.form[’username’] == ’admin’: return redirect(url_for(’success’)) return redirect(url_for(’index’))@app.route(’/success’)def success(): return ’logged in successfully’if __name__ == ’__main__’: app.run(debug=True)
下面給出的是 log_in.html的 HTML 腳本。
<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>Title</title></head><body> <form action = 'http://localhost:5000/login' method = 'POST'> <p>Enter Name:</p> <p><input type = 'text' name = 'username' /></p> <p><input type = 'submit' value = 'submit' /></p> </form></body></html>
Flask類(lèi)具有帶有錯(cuò)誤代碼的abort()函數(shù)。
Flask.abort(code)
Code參數(shù)采用以下值之一:
400 - 用于錯(cuò)誤請(qǐng)求 401 - 用于未身份驗(yàn)證的 403 - Forbidden 404 - 未找到 406 - 表示不接受 415 - 用于不支持的媒體類(lèi)型 429 - 請(qǐng)求過(guò)多讓我們對(duì)上述代碼中的login()函數(shù)稍作更改。如果要顯示’Unauthurized’頁(yè)面,請(qǐng)將其替換為調(diào)用abort(401),而不是重新顯示登錄頁(yè)面。
from flask import Flask, redirect, url_for, render_template, request, abortapp = Flask(__name__)@app.route(’/’)def index(): return render_template(’log_in.html’)@app.route(’/login’, methods=[’POST’, ’GET’])def login(): if request.method == ’POST’: if request.form[’username’] == ’admin’: return redirect(url_for(’success’)) else: abort(401) else: return redirect(url_for(’index’))@app.route(’/success’)def success(): return ’logged in successfully’if __name__ == ’__main__’: app.run(debug=True)
運(yùn)行,輸入非admin的用戶名,點(diǎn)擊提交
一個(gè)好的基于 GUI 的應(yīng)用程序會(huì)向用戶提供有關(guān)交互的反饋。例如,桌面應(yīng)用程序使用對(duì)話框或消息框,JavaScript 使用警報(bào)用于類(lèi)似目的。
在 Flask Web 應(yīng)用程序中生成這樣的信息性消息很容易。Flask 框架的閃現(xiàn)系統(tǒng)可以在一個(gè)視圖中創(chuàng)建消息,并在名為 next 的視圖函數(shù)中呈現(xiàn)它。
Flask 模塊包含 flash() 方法。它將消息傳遞給下一個(gè)請(qǐng)求,該請(qǐng)求通常是一個(gè)模板。
flash(message, category)
其中,
message 參數(shù)是要閃現(xiàn)的實(shí)際消息。 category 參數(shù)是可選的。它可以是“error”,“info”或“warning”。 為了從會(huì)話中獲取消息,模板調(diào)用 get_flashed_messages()。以下是一個(gè)完整的示例:
from flask import Flask, flash, redirect, render_template, request, url_forapp = Flask(__name__)app.secret_key = b’_5#y2L'F4Q8znxec]/’@app.route(’/’)def index(): return render_template(’index.html’)@app.route(’/login’, methods=[’GET’, ’POST’])def login(): error = None if request.method == ’POST’: if request.form[’username’] != ’admin’ or request.form[’password’] != ’secret’: error = ’Invalid credentials’ else: flash(’You were successfully logged in’) return redirect(url_for(’index’)) return render_template(’login.html’, error=error)if __name__ == ’__main__’: app.run(debug=True)
以下是實(shí)現(xiàn)閃現(xiàn)的 layout.html 模板:
<!doctype html><title>My Application</title>{% with messages = get_flashed_messages() %} {% if messages %} <ul class=flashes> {% for message in messages %} <li>{{ message }}</li> {% endfor %} </ul> {% endif %}{% endwith %}{% block body %}{% endblock %}
以下是繼承自 layout.html 的 index.html 模板:
{% block body %} <h1>Overview</h1> <p>Do you want to <a href='http://www.aoyou183.cn/bcjs/{{ url_for(’login’) }}'>log in?</a>{% endblock %}
以下是同樣繼承自 layout.html 的 login.html 模板:
{% extends 'layout.html' %}{% block body %} <h1>Login</h1> {% if error %} <p class=error><strong>Error:</strong> {{ error }} {% endif %} <form method=post> <dl> <dt>Username: <dd><input type=text name=username value='{{ request.form.username }}'> <dt>Password: <dd><input type=password name=password> </dl> <p><input type=submit value=Login> </form>{% endblock %}
運(yùn)行首頁(yè)
登錄報(bào)錯(cuò)頁(yè)
登錄成功頁(yè)
在 Flask 中處理文件上傳非常簡(jiǎn)單。它需要一個(gè) HTML 表單,其 enctype 屬性設(shè)置為’multipart/form-data’,將文件發(fā)布到 URL。URL 處理程序從 request.files[] 對(duì)象中提取文件,并將其保存到所需的位置。
每個(gè)上傳的文件首先會(huì)保存在服務(wù)器上的臨時(shí)位置,然后將其實(shí)際保存到它的最終位置。目標(biāo)文件的名稱可以是硬編碼的,也可以從 request.files[file] 對(duì)象的filename屬性中獲取。但是,建議使用 secure_filename() 函數(shù)獲取它的安全版本。可以在 Flask 對(duì)象的配置設(shè)置中定義默認(rèn)上傳文件夾的路徑和上傳文件的最大大小。
app.config[‘UPLOAD_FOLDER’] 定義上傳文件夾的路徑 app.config[‘MAX_CONTENT_LENGTH’] 指定要上傳的文件的最大大小(以字節(jié)為單位)
以下代碼具有 ’/upload’ URL 規(guī)則,該規(guī)則在 templates 文件夾中顯示 ’upload.html’,以及 ’/ upload-file’ URL 規(guī)則,用于調(diào)用 uploader() 函數(shù)處理上傳過(guò)程。’upload.html’ 有一個(gè)文件選擇器按鈕和一個(gè)提交按鈕。
<html><head> <title>File Upload</title></head><body> <form action='http://localhost:5000/uploader' method='POST' enctype='multipart/form-data'> <input type='file' name='file' accept='.jpg,.png' /> <input type='submit' /> </form></body></html>
以下是 Flask 應(yīng)用程序的 Python 代碼。
from flask import Flask, render_template, requestfrom werkzeug.utils import secure_filenameimport osapp = Flask(__name__)app.config[’UPLOAD_FOLDER’] = ’/Users/chenshifeng/upload/’@app.route(’/upload’)def upload_file(): return render_template(’upload.html’)@app.route(’/uploader’, methods = [’GET’, ’POST’])def uploader(): if request.method == ’POST’: f = request.files[’file’] f.save(os.path.join(app.config[’UPLOAD_FOLDER’],secure_filename(f.filename))) return ’file uploaded successfully’if __name__ == ’__main__’: app.run()
您將看到如下所示的界面。
選擇文件后,單擊提交。表單的 post 方法調(diào)用 ’/ upload_file’ URL。底層函數(shù) uploader() 執(zhí)行保存操作。上傳成功會(huì)顯示以下畫(huà)面:
上傳文件被放到/Users/chenshifeng/upload文件夾下:
Flask通常被稱為微框架,因?yàn)楹诵墓δ馨ɑ赪erkzeug的WSGI和路由以及基于Jinja2的模板引擎。此外,F(xiàn)lask框架還支持cookie和會(huì)話,以及JSON,靜態(tài)文件等Web幫助程序。顯然,這不足以開(kāi)發(fā)完整的Web應(yīng)用程序。而Flask擴(kuò)展就具備這樣的功能。Flask擴(kuò)展為Flask框架提供了可擴(kuò)展性。
有大量的Flask擴(kuò)展可用。Flask擴(kuò)展是一個(gè)Python模塊,它向Flask應(yīng)用程序添加了特定類(lèi)型的支持。Flask Extension Registry(Flask擴(kuò)展注冊(cè)表)是一個(gè)可用的擴(kuò)展目錄。可以通過(guò)pip實(shí)用程序下載所需的擴(kuò)展名。
在本教程中,我們將討論以下重要的Flask擴(kuò)展:
Flask Mail - 為Flask應(yīng)用程序提供SMTP接口 Flask WTF - 添加WTForms的渲染和驗(yàn)證 Flask SQLAlchemy - 為Flask應(yīng)用程序添加SQLAlchemy支持 Flask Sijax - Sijax的接口 - Python/jQuery庫(kù),使AJAX易于在Web應(yīng)用程序中使用每種類(lèi)型的擴(kuò)展通常提供有關(guān)其用法的大量文檔。由于擴(kuò)展是一個(gè)Python模塊,因此需要導(dǎo)入它才能使用它。Flask擴(kuò)展名通常命名為flask-foo。導(dǎo)入的操作如下:
from flask_foo import [class, function]
對(duì)于0.7以后的Flask版本,您還可以使用語(yǔ)法:
from flask.ext import foo
對(duì)于此用法,需要激活兼容性模塊。它可以通過(guò)運(yùn)行flaskext_compat.py來(lái)安裝:
import flaskext_compatflaskext_compat.activate()from flask.ext import foo14.1 Flask 郵件
務(wù)器建立簡(jiǎn)單的接口變得非常容易。
首先,應(yīng)該在pip實(shí)用程序的幫助下安裝Flask-Mail擴(kuò)展。
pip install Flask-Mail
然后需要通過(guò)設(shè)置以下應(yīng)用程序參數(shù)的值來(lái)配置Flask-Mail。
參數(shù) 描述 MAIL_SERVER 電子郵件服務(wù)器的名稱/IP地址 MAIL_PORT 使用的服務(wù)器的端口號(hào) MAIL_USE_TLS 啟用/禁用傳輸安全層加密 MAIL_USE_SSL 啟用/禁用安全套接字層加密 MAIL_DEBUG 調(diào)試支持。默認(rèn)值是Flask應(yīng)用程序的調(diào)試狀態(tài) MAIL_USERNAME 發(fā)件人的用戶名 MAIL_PASSWORD 發(fā)件人的密碼 MAIL_DEFAULT_SENDER 設(shè)置默認(rèn)發(fā)件人 MAIL_MAX_EMAILS 設(shè)置要發(fā)送的最大郵件數(shù) MAIL_SUPPRESS_SEND 如果app.testing設(shè)置為true,則發(fā)送被抑制 MAIL_ASCII_ATTACHMENTS 如果設(shè)置為true,則附加的文件名將轉(zhuǎn)換為ASCII
flask-mail模塊包含以下重要類(lèi)的定義。
14.1.1 Mail類(lèi)
它管理電子郵件消息傳遞需求。類(lèi)構(gòu)造函數(shù)采用以下形式:
flask-mail.Mail(app = None)
構(gòu)造函數(shù)將Flask應(yīng)用程序?qū)ο笞鳛閰?shù)。Mail類(lèi)的方法:
方法 描述 send() 發(fā)送Message類(lèi)對(duì)象的內(nèi)容 connect() 打開(kāi)與郵件主機(jī)的連接 send_message() 發(fā)送消息對(duì)象
14.1.2 Message類(lèi)
它封裝了一封電子郵件。Message類(lèi)構(gòu)造函數(shù)有幾個(gè)參數(shù):
flask-mail.Message(subject, recipients, body, html, sender, cc, bcc, reply-to, date, charset, extra_headers, mail_options,rcpt_options)
Message類(lèi)方法:
attach() - 為郵件添加附件。此方法采用以下參數(shù):
filename - 要附加的文件的名稱content_type - MIME類(lèi)型的文件data - 原始文件數(shù)據(jù)處置 - 內(nèi)容處置(如果有的話)。
add_recipient() - 向郵件添加另一個(gè)收件人
在下面的示例中,使用QQ郵箱服務(wù)的SMTP服務(wù)器用作Flask-Mail配置的MAIL_SERVER。
from flask import Flaskfrom flask_mail import Mail, Messageapp =Flask(__name__)mail=Mail(app)app.config[’MAIL_SERVER’]=’smtp.qq.com’app.config[’MAIL_PORT’] = 465app.config[’MAIL_USERNAME’] = ’[email protected]’app.config[’MAIL_PASSWORD’] = ’xxxxxxxx’app.config[’MAIL_USE_TLS’] = Falseapp.config[’MAIL_USE_SSL’] = Truemail = Mail(app)@app.route('/')def index(): msg = Message(’Hello’, sender = ’[email protected]’, recipients = [’[email protected]’]) msg.body = 'Hello Flask message sent from Flask-Mail' mail.send(msg) return 'Sent'if __name__ == ’__main__’: app.run(debug = True)
步驟1 - 安裝Flask-SQLAlchemy擴(kuò)展。
pip install flask-sqlalchemy
步驟2 - 您需要從此模塊導(dǎo)入SQLAlchemy類(lèi)。
from flask_sqlalchemy import SQLAlchemy
步驟3 - 現(xiàn)在創(chuàng)建一個(gè)Flask應(yīng)用程序?qū)ο蟛橐褂玫臄?shù)據(jù)庫(kù)設(shè)置URI。
app = Flask(__name__)app.config[’SQLALCHEMY_DATABASE_URI’] = ’sqlite:///students.sqlite3’
步驟4 - 然后使用應(yīng)用程序?qū)ο笞鳛閰?shù)創(chuàng)建SQLAlchemy類(lèi)的對(duì)象。該對(duì)象包含用于ORM操作的輔助函數(shù)。它還提供了一個(gè)父Model類(lèi),使用它來(lái)聲明用戶定義的模型。在下面的代碼段中,創(chuàng)建了students模型。
db = SQLAlchemy(app)class students(db.Model): id = db.Column(’student_id’, db.Integer, primary_key = True) name = db.Column(db.String(100)) city = db.Column(db.String(50)) addr = db.Column(db.String(200)) pin = db.Column(db.String(10))def __init__(self, name, city, addr,pin): self.name = name self.city = city self.addr = addr self.pin = pin
步驟5 - 要?jiǎng)?chuàng)建/使用URI中提及的數(shù)據(jù)庫(kù),請(qǐng)運(yùn)行create_all()方法。
db.create_all()
SQLAlchemy的Session對(duì)象管理ORM對(duì)象的所有持久性操作。以下session方法執(zhí)行CRUD操作:
db.session.add (模型對(duì)象) - 將記錄插入到映射表中 db.session.delete (模型對(duì)象) - 從表中刪除記錄 model.query.all() - 從表中檢索所有記錄(對(duì)應(yīng)于SELECT查詢)。您可以通過(guò)使用filter屬性將過(guò)濾器應(yīng)用于檢索到的記錄集。例如,要在學(xué)生表中檢索city =’Hyderabad’的記錄,請(qǐng)使用以下語(yǔ)句:
Students.query.filter_by(city = ’Hyderabad’).all()
有了這么多的背景,現(xiàn)在我們將為我們的應(yīng)用程序提供視圖函數(shù)來(lái)添加學(xué)生數(shù)據(jù)。
應(yīng)用程序的入口點(diǎn)是綁定到’/’ URL的show_all()函數(shù)。學(xué)生表的記錄集作為參數(shù)發(fā)送到HTML模板。模板中的服務(wù)器端代碼以HTML表格形式呈現(xiàn)記錄。
@app.route(’/’)def show_all(): return render_template(’show_all.html’, students = students.query.all() )
模板(’show_all.html’)的HTML腳本如下:
<!DOCTYPE html><html lang = 'en'> <head></head> <body> <h3> <a href = 'http://www.aoyou183.cn/bcjs/{{ url_for(’show_all’) }}'>Comments - Flask SQLAlchemy example</a> </h3> <hr/> {%- for message in get_flashed_messages() %} {{ message }} {%- endfor %} <h3>Students (<a href = 'http://www.aoyou183.cn/bcjs/{{ url_for(’new’) }}'>Add Student </a>)</h3> <table> <thead> <tr> <th>Name</th> <th>City</th> <th>Address</th> <th>Pin</th> </tr> </thead> <tbody> {% for student in students %} <tr> <td>{{ student.name }}</td> <td>{{ student.city }}</td> <td>{{ student.addr }}</td> <td>{{ student.pin }}</td> </tr> {% endfor %} </tbody> </table> </body></html>
上述網(wǎng)頁(yè)包含指向’/ new’ URL映射new()函數(shù)的超鏈接。單擊時(shí),將打開(kāi)“學(xué)生信息”表單。 數(shù)據(jù)在 POST方法中發(fā)布到相同的URL。new.html
<!DOCTYPE html><html> <body> <h3>Students - Flask SQLAlchemy example</h3> <hr/> {%- for category, message in get_flashed_messages(with_categories = true) %} <div class = 'alert alert-danger'> {{ message }} </div> {%- endfor %} <form action = '{{ request.path }}' method = 'post'> <label for = 'name'>Name</label><br> <input type = 'text' name = 'name' placeholder = 'Name' /><br> <label for = 'email'>City</label><br> <input type = 'text' name = 'city' placeholder = 'city' /><br> <label for = 'addr'>addr</label><br> <textarea name = 'addr' placeholder = 'addr'></textarea><br> <label for = 'PIN'>PINCODE</label><br> <input type = 'text' name = 'pin' placeholder = 'pin' /><br> <input type = 'submit' value = 'Submit' /> </form> </body></html>
當(dāng)http方法被檢測(cè)為POST時(shí),表單數(shù)據(jù)被添加到學(xué)生表中,并且應(yīng)用返回到顯示添加數(shù)據(jù)的主頁(yè)。
@app.route(’/new’, methods = [’GET’, ’POST’])def new(): if request.method == ’POST’: if not request.form[’name’] or not request.form[’city’] or not request.form[’addr’]: flash(’Please enter all the fields’, ’error’) else: student = students(request.form[’name’], request.form[’city’], request.form[’addr’], request.form[’pin’]) db.session.add(student) db.session.commit() flash(’Record was successfully added’) return redirect(url_for(’show_all’)) return render_template(’new.html’)
下面給出了應(yīng)用程序(app.py)的完整代碼。
from flask import Flask, request, flash, url_for, redirect, render_templatefrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config[’SQLALCHEMY_DATABASE_URI’] = ’sqlite:///students.sqlite3’app.config[’SECRET_KEY’] = 'random string'db = SQLAlchemy(app)class students(db.Model): id = db.Column(’student_id’, db.Integer, primary_key=True) name = db.Column(db.String(100)) city = db.Column(db.String(50)) addr = db.Column(db.String(200)) pin = db.Column(db.String(10)) def __init__(self, name, city, addr, pin): self.name = name self.city = city self.addr = addr self.pin = [email protected](’/’)def show_all(): return render_template(’show_all.html’, students=students.query.all())@app.route(’/new’, methods=[’GET’, ’POST’])def new(): if request.method == ’POST’: if not request.form[’name’] or not request.form[’city’] or not request.form[’addr’]: flash(’Please enter all the fields’, ’error’) else: student = students(request.form[’name’], request.form[’city’],request.form[’addr’], request.form[’pin’]) db.session.add(student) db.session.commit() flash(’Record was successfully added’) return redirect(url_for(’show_all’)) return render_template(’new.html’)if __name__ == ’__main__’: db.create_all() app.run(debug=True)
首頁(yè)
錯(cuò)誤頁(yè):
提交成功頁(yè):
本文參考:https://www.w3cschool.cn/flask/
到此這篇關(guān)于python flask框架詳解的文章就介紹到這了,更多相關(guān)python flask框架內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. CSS3實(shí)例分享之多重背景的實(shí)現(xiàn)(Multiple backgrounds)2. XHTML 1.0:標(biāo)記新的開(kāi)端3. HTML5 Canvas繪制圖形從入門(mén)到精通4. XML解析錯(cuò)誤:未組織好 的解決辦法5. ASP基礎(chǔ)知識(shí)VBScript基本元素講解6. asp(vbscript)中自定義函數(shù)的默認(rèn)參數(shù)實(shí)現(xiàn)代碼7. 詳解CSS偽元素的妙用單標(biāo)簽之美8. 利用CSS3新特性創(chuàng)建透明邊框三角9. 使用Spry輕松將XML數(shù)據(jù)顯示到HTML頁(yè)的方法10. XML入門(mén)的常見(jiàn)問(wèn)題(四)
