Flask是一個Python編寫的Web 微框架,讓咱們可使用Python語言快速實現一個網站或Web服務。本文參考自Flask官方文檔,
英文很差的同窗也能夠參考中文文檔javascript
1.安裝flask
pip install flask
2.簡單上手
一個最小的 Flask 應用以下:css
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run()
代碼解析:
一、首先咱們導入了 Flask 類。 該類的實例將會成為咱們的 WSGI 應用。
二、接著咱們建立一個該類的實例。第一個參數是應用模塊或者包的名稱。若是你使用 一個單一模塊(就像本例),那么應當使用 name ,由于名稱會根據這個 模塊是按應用方式使用仍是做為一個模塊導入而發生變化(多是 ‘main’ , 也多是實際導入的名稱)。這個參數是必需的,這樣 Flask 才能知道在哪里能夠 找到模板和靜態文件等東西
三、而后咱們使用 route() 裝飾器來告訴 Flask 觸發函數的 URL 。
四、函數名稱被用于生成相關聯的 URL 。函數最后返回須要在用戶瀏覽器中顯示的信息。html
運行結果:java
* Serving Flask app "flask_demo" (lazy loading)
* Environment: production
WARNING: 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)
訪問:http://127.0.0.1:5000/
python
app.route(rule, options)
- rule 參數表示與該函數的URL綁定。
-
options 是要轉發給基礎Rule對象的參數列表。
在上面的示例中,'/ ' URL與hello_world()函數綁定。所以,當在瀏覽器中打開web服務器的主頁時,將呈現該函數的輸出。
最后,Flask類的run()方法在本地開發服務器上運行應用程序。
app.run(host, port, debug, options)
全部參數都是可選的web
- host:要監聽的主機名。 默認為127.0.0.1(localhost)。設置為“0.0.0.0”以使服務器在外部可用
- port :默認值為5000
- debug:默認為false。 若是設置為true,則提供調試信息,能夠自動重載代碼并顯示調試信息
- options:要轉發到底層的Werkzeug服務器。
2.1 調試模式
雖然 flask 命令能夠方便地啟動一個本地開發服務器,可是每次應用代碼 修改以后都須要手動重啟服務器。這樣不是很方便, Flask 能夠作得更好。若是你打開 調試模式,那么服務器會在修改應用代碼以后自動重啟,而且當應用出錯時還會提供一個 有用的調試器。
在命令行中,若是須要打開全部開發功能(包括調試模式),那么要在運行服務器以前導出 FLASK_ENV 環境變量并把其設置為 development:sql
$ export FLASK_ENV=development
$ flask run
在代碼中,在運行或將調試參數傳遞給run()方法以前,經過將application對象的debug屬性設置為True來啟用Debug模式。數據庫
app.debug = True
app.run()
# 或者
app.run(debug = True)
2.2 綁定IP和端口
默認狀況下,Flask綁定IP為127.0.0.1,端口為5000。咱們也能夠經過下面的方式自定義:flask
app.run(host='0.0.0.0', port=80, debug=True)
0.0.0.0表明電腦全部的IP。80是HTTP網站服務的默認端口。什么是默認?好比,咱們訪問網站http://www.example.com,實際上是訪問的http://www.example.com:80,只不過:80能夠省略不寫。瀏覽器
3.Flask 路由
現代Web框架使用路由技術來幫助用戶記住應用程序URL。能夠直接訪問所需的頁面,而無需從主頁導航。
Flask中的route()裝飾器用于將URL綁定到函數。例如:
@app.route('/hello')
def hello_world():
return 'hello world'
在這里,URL'/ hello'
規則綁定到hello_world()函數。 所以,若是用戶訪問http://localhost:5000/hello
URL,hello_world()函數的輸出將在瀏覽器中呈現。
application對象的add_url_rule()函數也可用于將URL與函數綁定,如上例所示,使用route()裝飾器的目的也由如下表示:
def hello_world():
return 'hello world'
app.add_url_rule('/', 'hello', hello_world)
4.Flask 變量規則
經過向規則參數添加變量部分,能夠動態構建URL。此變量部分標記為 <converter:variable_name>
。它做為關鍵字參數傳遞給與規則相關聯的函數。
在如下示例中,route()裝飾器的規則參數包含附加到URL'/hello'
的<name>
。 所以,若是在瀏覽器中輸入http://localhost:5000/hello/chenshifeng做為URL,則'chenshifeng'將做為參數提供給 hello()函數。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:chenshifeng
@file:flask_demo.py
@time:2021/03/01
"""
from flask import Flask
app = Flask(__name__)
@app.route('/hello/<name>')
def hello_name(name):
return 'Hello %s!' % name
if __name__ == '__main__':
app.run(debug=True)
運行,訪問:http://localhost:5000/hello/chenshifeng
除了默認字符串變量部分以外,還可使用如下轉換器構建規則:
轉換器 | 描述 |
---|---|
string | (缺省值) 接受任何不包含斜杠的文本 |
int | 接受正整數 |
float | 接受正浮點數 |
path | 相似 string ,但能夠包含斜杠 |
uuid | 接受 UUID 字符串 |
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:chenshifeng
@file:flask_demo.py
@time:2021/03/01
"""
from flask import Flask
app = 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' % post_id
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
# show the subpath after /path/
return 'Subpath %s' % subpath
if __name__ == '__main__':
app.run(debug=True)
4.1惟一的 URL / 重定向行為
如下兩條規則的不一樣之處在因而否使用尾部的斜杠。:
@app.route('/projects/')
def projects():
return 'The project page'
@app.route('/about')
def about():
return 'The about page'
projects 的 URL 是中規中矩的,尾部有一個斜杠,看起來就如同一個文件夾。 訪問一個沒有斜杠結尾的 URL 時 Flask 會自動進行重定向,幫你在尾部加上一個斜杠。
about 的 URL 沒有尾部斜杠,所以其行為表現與一個文件相似。若是訪問這個 URL 時添加了尾部斜杠就會獲得一個 404 錯誤。這樣能夠保持 URL 惟一,并幫助 搜索引擎避免重復索引同一頁面。
5.Flask URL構建
url_for()函數對于動態構建特定函數的URL很是有用。該函數接受函數的名稱做為第一個參數,以及一個或多個關鍵字參數,每一個參數對應于URL的變量部分。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:chenshifeng
@file:flask_demo.py
@time:2021/03/01
"""
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/admin')
def hello_admin():
return 'Hello Admin'
@app.route('/guest/<guest>')
def hello_guest(guest):
return 'Hello %s as Guest' % guest
@app.route('/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函數用于重定向,實現機制很簡單,就是向客戶端(瀏覽器)發送一個重定向的HTTP報文,瀏覽器會去訪問報文中指定的url。
運行
打開瀏覽器并輸入URL - http://localhost:5000/user/admin
Hello Admin
在瀏覽器中輸入如下URL - http://localhost:5000/user/mvl
Hello mvl as Guest
6.Flask HTTP方法
Web 應用使用不一樣的 HTTP 方法處理 URL 。當你使用 Flask 時,應當熟悉 HTTP 方法。 缺省狀況下,一個路由只回應 GET 請求。 可使用 route() 裝飾器的 methods 參數來處理不一樣的 HTTP 方法:
方法 | 描述 |
---|---|
GET | 以未加密的形式將數據發送到服務器,最多見的方法。 |
HEAD | 和GET方法相同,但沒有響應體。 |
POST | 用于將HTML表單數據發送到服務器,POST方法接收的數據不禁服務器緩存。 |
PUT | 用上傳的內容替換目標資源的全部當前表示。 |
DELETE | 刪除由URL給出的目標資源的全部當前表示。 |
默認狀況下,Flask路由響應GET請求。可是,能夠經過為route()裝飾器提供方法參數來更改此首選項。
為了演示在URL路由中使用POST方法,首先讓咱們建立一個HTML表單,并使用POST方法將表單數據發送到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>
運行如下代碼
from flask import Flask, redirect, url_for, request
app = Flask(__name__)
@app.route('/success/<name>')
def success(name):
return 'welcome %s' % name
@app.route('/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)
在瀏覽器中打開login.html,在文本字段中輸入name,而后單擊提交。
表單數據將POST到表單標簽的action子句中的URL。
http://localhost/login映射到login()函數。因為服務器經過POST方法接收數據,所以經過如下步驟得到從表單數據得到的“nm”參數的值:
表單數據將POST到表單標簽的action子句中的URL。
user = request.form['nm']
它做為變量部分傳遞給'/ success' URL。瀏覽器在窗口中顯示welcome消息。
在login.html中將方法參數更改成'GET',而后在瀏覽器中再次打開它。服務器上接收的數據是經過GET方法得到的。經過如下的步驟得到'nm'參數的值:
User = request.args.get('nm')
這里,args是包含表單參數對及其對應值對的列表的字典對象。與'nm'參數對應的值將像以前同樣傳遞到'/ success' URL。
7.Flask 模板
在大型應用中,把業務邏輯和表現內容放在一塊兒,會增長代碼的復雜度和維護成本.
- 模板實際上是一個包含響應文本的文件,其中用占位符(變量)表示動態部分,告訴模板引擎其具體的值須要從使用的數據中獲取
- 使用真實值替換變量,再返回最終獲得的字符串,這個過程稱為'渲染'
- Flask 是使用 Jinja2 這個模板引擎來渲染模板
使用模板的好處
- 視圖函數只負責業務邏輯和數據處理(業務邏輯方面)
- 而模板則取到視圖函數的數據結果進行展現(視圖展現方面)
- 代碼結構清晰,耦合度低
使用 render_template() 方法能夠渲染模板,你只要提供模板名稱和須要 做為參數傳遞給模板的變量就好了。
Flask 會在 templates 文件夾內尋找模板。所以,若是你的應用是一個模塊, 那么模板文件夾應該在模塊旁邊;若是是一個包,那么就應該在包里面:
情形 1 : 一個模塊:
/application.py
/templates
/hello.html
情形 2 : 一個包:
/application
/__init__.py
/templates
/hello.html
示例代碼:
from flask import Flask, render_template
app = 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方法:渲染模板
# 參數1: 模板名稱 參數n: 傳到模板里的數據
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數據獲取</h2>
<hr>
{{ my_list[0] }}
<br>
{{ my_list.1 }}
<hr>
<h2>字典數據獲取</h2>
<hr>
{{ my_dict['name'] }}
<br>
{{ my_dict.age }}
<hr>
<h2>算術運算</h2>
<br>
{{ my_list.0 + 10 }}
<br>
{{ my_list[0] + my_list.1 }}
</body>
</html>
運行效果:
8.Flask 靜態文件
動態的 web 應用也須要靜態文件,通常是 CSS 和 JavaScript 文件。理想狀況下你的 服務器已經配置好了為你的提供靜態文件的服務。可是在開發過程當中, Flask 也能作好 這項工做。只要在你的包或模塊旁邊建立一個名為 static 的文件夾就好了。 靜態文件位于應用的 /static 中。
使用特定的 'static' 端點就能夠生成相應的 URL
url_for('static', filename='style.css')
這個靜態文件在文件系統中的位置應該是 static/style.css 。
在下面的示例中,在index.html中的HTML按鈕的OnClick事件上調用hello.js中定義的javascript函數,該函數在Flask應用程序的“/”URL上呈現。
from flask import Flask, render_template
app = 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 = "{{ url_for('static', filename = 'hello.js') }}" ></script>
</head>
<body>
<input type = "button" onclick = "sayHello()" value = "Say Hello" />
</body>
</html>
Hello.js包含sayHello()函數。
function sayHello() {
alert("Hello World")
}
運行效果:
9.Flask Request對象
來自客戶端網頁的數據做為全局請求對象發送到服務器。為了處理請求數據,應該從Flask模塊導入。
Request對象的重要屬性以下所列:
- form - 它是一個字典對象,包含表單參數及其值的鍵和值對。
- args - 解析查詢字符串的內容,它是問號(?)以后的URL的一部分。
- Cookies - 保存Cookie名稱和值的字典對象。
- files - 與上傳文件有關的數據。
- method - 當前請求方法
首先,你必須從 flask 模塊導入請求對象:
from flask import request
9.1 Flask 將表單數據發送到模板
咱們已經看到,能夠在 URL 規則中指定 http 方法。觸發函數接收的 Form 數據能夠以字典對象的形式收集它并將其轉發到模板以在相應的網頁上呈現它。
在如下示例中,'/' URL 會呈現具備表單的網頁(student.html)。填入的數據會發布到觸發 result() 函數的 '/result' URL。
result() 函數收集字典對象中的 request.form 中存在的表單數據,并將其發送給 result.html。
該模板動態呈現表單數據的 HTML 表格。
下面給出的是應用程序的 Python 代碼:
from flask import Flask, render_template, request
app = 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>
運行效果:
運行 Python 腳本,并在瀏覽器中輸入 URL http://localhost:5000/。
當點擊提交按鈕時,表單數據以 HTML 表格的形式呈如今 result.html 上。
9.2 Flask Cookies
Cookie以文本文件的形式存儲在客戶端的計算機上。其目的是記住和跟蹤與客戶使用相關的數據,以得到更好的訪問者體驗和網站統計信息。
Request對象包含Cookie的屬性。它是全部cookie變量及其對應值的字典對象,客戶端已傳輸。除此以外,cookie還存儲其網站的到期時間,路徑和域名。
在Flask中,對cookie的處理步驟為:
-
設置cookie:
設置cookie,默認有效期是臨時cookie,瀏覽器關閉就失效
能夠經過 max_age 設置有效期, 單位是秒
resp = make_response("success") # 設置響應體
resp.set_cookie("chenshifeng", "shifengboy", max_age=3600)
-
獲取cookie
獲取cookie,經過request.cookies的方式, 返回的是一個字典,能夠獲取字典里的相應的值
cookie_1 = request.cookies.get("chenshifeng")
-
刪除cookie
這里的刪除只是讓cookie過時,并非直接刪除cookie
刪除cookie,經過delete_cookie()的方式, 里面是cookie的名字
resp = make_response("del success") # 設置響應體
resp.delete_cookie("chenshifeng")
如下為Flask Cookies的簡單示例:
from flask import Flask, make_response, request
app = Flask(__name__)
@app.route("/set_cookies")
def set_cookie():
resp = make_response("success")
resp.set_cookie("chenshifeng", "shifengboy",max_age=3600)
return resp
@app.route("/get_cookies")
def get_cookie():
cookie_1 = request.cookies.get("chenshifeng") # 獲取名字為Itcast_1對應cookie的值
return cookie_1
@app.route("/delete_cookies")
def delete_cookie():
resp = make_response("del success")
resp.delete_cookie("chenshifeng")
return resp
if __name__ == '__main__':
app.run(debug=True)
設置cookies
運行應用程序,在瀏覽器中輸入 127.0.0.1:5000/set_cookies 來設置cookies,設置 cookies 的輸出以下所示:
獲取cookie
根據視圖函數中相對應的路徑,輸入 http://127.0.0.1:5000/get_cookies ,讀回 cookies 的輸出以下所示:
刪除cookie
根據視圖函數中相對應的路徑,輸入 http://127.0.0.1:5000/delete_cookies ,刪除 cookies 的輸出以下所示:
注意刪除,只是讓 cookie 過時。
10.Flask 會話
與Cookie不一樣,Session(會話)數據存儲在服務器上。會話是客戶端登陸到服務器并注銷服務器的時間間隔。須要在該會話中保存的數據會存儲在服務器上的臨時目錄中。
為每一個客戶端的會話分配會話ID。會話數據存儲在cookie的頂部,服務器以加密方式對其進行簽名。對于此加密,Flask應用程序須要一個定義的SECRET_KEY。
Session對象也是一個字典對象,包含會話變量和關聯值的鍵值對。
例如,要設置一個'username'會話變量,請使用如下語句:
Session['username'] = 'admin'
要釋放會話變量,請使用pop()方法。
session.pop('username', None)
演示代碼:
from flask import Flask, session, redirect, url_for, request
app = Flask(__name__)
app.secret_key = 'fkdjsafjdkfdlkjfadskjfadskljdsfklj' # 確保設置應用程序的secret_key
@app.route('/')
def index():
if 'username' in session:
username = session['username']
return '登陸用戶名是:' + username + '<br>' + \
"<b><a href = '/logout'>點擊這里注銷</a></b>"
return "您暫未登陸, <br><a href = '/login'></b>" + \
"點擊這里登陸</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)
如何生成一個好的密鑰
生成隨機數的關鍵在于一個好的隨機種子,所以一個好的密鑰應當有足夠的隨機性。 操做系統能夠有多種方式基于密碼隨機生成器來生成隨機數據。使用下面的命令 能夠快捷的為 Flask.secret_key ( 或者 SECRET_KEY )生成值:
$ python -c 'import os; print(os.urandom(16))'
b'_5#y2L"F4Q8z\n\xec]/'
訪問http://127.0.0.1:5000/,只是提示用戶登陸,由于未設置會話變量'username'。
當用戶點擊登陸,瀏覽到“/login”login()視圖函數時,由于它是經過GET方法調用的,因此將打開一個登陸表單。
點擊登陸,經過POST方法將表單發送回'/login',如今會話變量已設置。應用程序重定向到'/'。此時會話變量'username'被找到。
應用程序還包含一個logout()視圖函數,它會彈出'username'會話變量。所以,'/' URL再次顯示開始頁面。
11.Flask 重定向和錯誤
Flask類有一個redirect()函數。調用時,它返回一個響應對象,并將用戶重定向到具備指定狀態代碼的另外一個目標位置。
redirect()函數的原型以下:
Flask.redirect(location, statuscode, response)
在上述函數中:
- location參數是應該重定向響應的URL。
- statuscode發送到瀏覽器標頭,默認為302。
- response參數用于實例化響應。
如下狀態代碼已標準化:
- 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
默認狀態代碼為302,表示'found'。
在如下示例中,redirect()函數用于在登陸嘗試失敗時再次顯示登陸頁面。
from flask import Flask, redirect, url_for, render_template, request
# Initialize the Flask application
app = 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類具備帶有錯誤代碼的abort()函數。
Flask.abort(code)
Code參數采用如下值之一:
- 400 - 用于錯誤請求
- 401 - 用于未身份驗證的
- 403 - Forbidden
- 404 - 未找到
- 406 - 表示不接受
- 415 - 用于不支持的媒體類型
-
429 - 請求過多
讓咱們對上述代碼中的login()函數稍做更改。若是要顯示'Unauthurized'頁面,請將其替換為調用abort(401),而不是從新顯示登陸頁面。
from flask import Flask, redirect, url_for, render_template, request, abort
app = 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)
運行,輸入非admin的用戶名,點擊提交
12. Flask 消息閃現
一個好的基于 GUI 的應用程序會向用戶提供有關交互的反饋。例如,桌面應用程序使用對話框或消息框,JavaScript 使用警報用于相似目的。
在 Flask Web 應用程序中生成這樣的信息性消息很容易。Flask 框架的閃現系統能夠在一個視圖中建立消息,并在名為 next 的視圖函數中呈現它。
Flask 模塊包含 flash() 方法。它將消息傳遞給下一個請求,該請求一般是一個模板。
flash(message, category)
其中,
- message 參數是要閃現的實際消息。
-
category 參數是可選的。它能夠是“error”,“info”或“warning”。
為了從會話中獲取消息,模板調用 get_flashed_messages()。
如下是一個完整的示例:
from flask import Flask, flash, redirect, render_template, \
request, url_for
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
@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)
如下是實現閃現的 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="{{ 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 %}
運行
首頁
登陸報錯頁
登陸成功頁
13. Flask 文件上傳
在 Flask 中處理文件上傳很是簡單。它須要一個 HTML 表單,其 ?enctype?
屬性設置為'multipart/form-data?'
,將文件發布到 URL。URL 處理程序從 ?request.files[]?
對象中提取文件,并將其保存到所需的位置。
每一個上傳的文件首先會保存在服務器上的臨時位置,而后將其實際保存到它的最終位置。目標文件的名稱能夠是硬編碼的,也能夠從 ?request.files[file]
?對象的?filename
?屬性中獲取。可是,建議使用 ?secure_filename()?
函數獲取它的安全版本。
能夠在 Flask 對象的配置設置中定義默認上傳文件夾的路徑和上傳文件的最大大小。
app.config[‘UPLOAD_FOLDER’] 定義上傳文件夾的路徑 app.config[‘MAX_CONTENT_LENGTH’] 指定要上傳的文件的最大大小(以字節為單位)
如下代碼具備 ?'/upload'
?URL 規則,該規則在 templates 文件夾中顯示? 'upload.html'?
,以及 ?'/ upload-file'
?URL 規則,用于調用 ?uploader() ?
函數處理上傳過程。
?'upload.html'
?有一個文件選擇器按鈕和一個提交按鈕。
<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 應用程序的 Python 代碼。
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os
app = 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 ?方法調用? '/ upload_file'?
URL。底層函數 ?uploader()?
執行保存操做。
上傳成功會顯示如下畫面:
上傳文件被放到/Users/chenshifeng/upload文件夾下:
14. Flask 擴展
Flask一般被稱為微框架,由于核心功能包括基于Werkzeug的WSGI和路由以及基于Jinja2的模板引擎。此外,Flask框架還支持cookie和會話,以及JSON,靜態文件等Web幫助程序。顯然,這不足以開發完整的Web應用程序。而Flask擴展就具有這樣的功能。Flask擴展為Flask框架提供了可擴展性。
有大量的Flask擴展可用。Flask擴展是一個Python模塊,它向Flask應用程序添加了特定類型的支持。Flask Extension Registry(Flask擴展注冊表)是一個可用的擴展目錄。能夠經過pip實用程序下載所需的擴展名。
在本教程中,咱們將討論如下重要的Flask擴展:
- Flask Mail - 為Flask應用程序提供SMTP接口
- Flask WTF - 添加WTForms的渲染和驗證
- Flask SQLAlchemy - 為Flask應用程序添加SQLAlchemy支持
- Flask Sijax - Sijax的接口 - Python/jQuery庫,使AJAX易于在Web應用程序中使用
每種類型的擴展一般提供有關其用法的大量文檔。因為擴展是一個Python模塊,所以須要導入它才能使用它。Flask擴展名一般命名為flask-foo。導入的操做以下:
from flask_foo import [class, function]
對于0.7之后的Flask版本,您還可使用語法:
from flask.ext import foo
對于此用法,須要激活兼容性模塊。它能夠經過運行flaskext_compat.py來安裝:
import flaskext_compat
flaskext_compat.activate()
from flask.ext import foo
14.1 Flask 郵件
務器創建簡單的接口變得很是容易。
首先,應該在pip實用程序的幫助下安裝Flask-Mail擴展。
pip install Flask-Mail
而后須要經過設置如下應用程序參數的值來配置Flask-Mail。
參數 | 描述 |
---|---|
MAIL_SERVER | 電子郵件服務器的名稱/IP地址 |
MAIL_PORT | 使用的服務器的端口號 |
MAIL_USE_TLS | 啟用/禁用傳輸安全層加密 |
MAIL_USE_SSL | 啟用/禁用安全套接字層加密 |
MAIL_DEBUG | 調試支持。默認值是Flask應用程序的調試狀態 |
MAIL_USERNAME | 發件人的用戶名 |
MAIL_PASSWORD | 發件人的密碼 |
MAIL_DEFAULT_SENDER | 設置默認發件人 |
MAIL_MAX_EMAILS | 設置要發送的最大郵件數 |
MAIL_SUPPRESS_SEND | 若是app.testing設置為true,則發送被抑制 |
MAIL_ASCII_ATTACHMENTS | 若是設置為true,則附加的文件名將轉換為ASCII |
flask-mail模塊包含如下重要類的定義。
14.1.1 Mail類
它管理電子郵件消息傳遞需求。類構造函數采用如下形式:
flask-mail.Mail(app = None)
構造函數將Flask應用程序對象做為參數。
Mail類的方法:
方法 | 描述 |
---|---|
send() | 發送Message類對象的內容 |
connect() | 打開與郵件主機的鏈接 |
send_message() | 發送消息對象 |
14.1.2 Message類
它封裝了一封電子郵件。Message類構造函數有幾個參數:
flask-mail.Message(subject, recipients, body, html, sender, cc, bcc, reply-to, date, charset, extra_headers, mail_options,rcpt_options)
Message類方法:
-
attach() - 為郵件添加附件。此方法采用如下參數:
- filename - 要附加的文件的名稱
- content_type - MIME類型的文件
- data - 原始文件數據
- 處置 - 內容處置(若是有的話)。
-
add_recipient() - 向郵件添加另外一個收件人
在下面的示例中,使用QQ郵箱服務的SMTP服務器用做Flask-Mail配置的MAIL_SERVER。
from flask import Flask
from flask_mail import Mail, Message
app =Flask(__name__)
mail=Mail(app)
app.config['MAIL_SERVER']='smtp.qq.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = '[email protected]'
app.config['MAIL_PASSWORD'] = 'xxxxxxxx'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = 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)
15. Flask SQLAlchemy
步驟1 - 安裝Flask-SQLAlchemy擴展。
pip install flask-sqlalchemy
步驟2 - 您須要今后模塊導入SQLAlchemy類。
from flask_sqlalchemy import SQLAlchemy
步驟3 - 如今建立一個Flask應用程序對象并為要使用的數據庫設置URI。
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///students.sqlite3'
步驟4 - 而后使用應用程序對象做為參數建立SQLAlchemy類的對象。該對象包含用于ORM操做的輔助函數。它還提供了一個父Model類,使用它來聲明用戶定義的模型。在下面的代碼段中,建立了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 - 要建立/使用URI中說起的數據庫,請運行create_all()方法。
db.create_all()
SQLAlchemy的Session對象管理ORM對象的全部持久性操做。
如下session方法執行CRUD操做:
- db.session.add (模型對象) - 將記錄插入到映射表中
- db.session.delete (模型對象) - 從表中刪除記錄
-
model.query.all() - 從表中檢索全部記錄(對應于SELECT查詢)。
您能夠經過使用filter屬性將過濾器應用于檢索到的記錄集。例如,要在學生表中檢索city ='Hyderabad'的記錄,請使用如下語句:
Students.query.filter_by(city = ’Hyderabad’).all()
有了這么多的背景,如今咱們將為咱們的應用程序提供視圖函數來添加學生數據。
應用程序的入口點是綁定到'/' URL的show_all()函數。學生表的記錄集做為參數發送到HTML模板。模板中的服務器端代碼以HTML表格形式呈現記錄。
@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 = "{{ url_for('show_all') }}">Comments - Flask
SQLAlchemy example</a>
</h3>
<hr/>
{%- for message in get_flashed_messages() %}
{{ message }}
{%- endfor %}
<h3>Students (<a href = "{{ 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>
上述網頁包含指向'/ new' URL映射new()函數的超連接。單擊時,將打開“學生信息”表單。 數據在 POST方法中發布到相同的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>
當http方法被檢測為POST時,表單數據被添加到學生表中,而且應用返回到顯示添加數據的主頁。
@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')
下面給出了應用程序(app.py)的完整代碼。
from flask import Flask, request, flash, url_for, redirect, render_template
from flask_sqlalchemy import SQLAlchemy
app = 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 = pin
@app.route('/')
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)
首頁
錯誤頁:
提交成功頁:
本文參考:https://www.w3cschool.cn/flask/
到此這篇關于python flask框架詳解的文章就介紹到這了,更多相關python flask框架內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://www.cnblogs.com/feng0815/p/14488963.html