Flask 框架學(xué)習(xí)文檔
概述
Flask 是一個使用 Python 編寫的 Web 框架冤留。它的設(shè)計目標是簡單奶躯、輕量級、易擴展特漩,并且具有良好的靈活性和可定制性隔盛。Flask 提供了基本的路由、請求處理拾稳、模板渲染、Cookie 管理等功能腊脱,同時也可以借助豐富的擴展庫來實現(xiàn)更加復(fù)雜的功能访得。Flask 尤其適用于開發(fā)小型 Web 應(yīng)用、API 和原型系統(tǒng)等陕凹。
Flask 使用基于 Werkzeug 和 Jinja2 的內(nèi)核悍抑,其中 Werkzeug 提供了 HTTP 協(xié)議相關(guān)的基礎(chǔ)功能,如 HTTP 服務(wù)器杜耙、請求響應(yīng)處理搜骡、URL 路由等,而 Jinja2 提供了模板渲染機制佑女。Flask 本身只提供了這兩個基礎(chǔ)依賴的封裝记靡,并且易于擴展。
安裝和使用
使用 Flask 前需要安裝 Python 環(huán)境团驱,并通過 pip 安裝 Flask 庫摸吠。安裝完成后,我們可以編寫簡單的 Flask 應(yīng)用程序:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello world!'
if __name__ == '__main__':
app.run()
運行該腳本嚎花,F(xiàn)lask 就會在本地啟動一個 HTTP 服務(wù)器寸痢,監(jiān)聽默認端口 5000,并提供一個 URL 為 / 的路由紊选,當用戶訪問該 URL 時啼止,會返回一個字符串 “Hello world!”道逗,即 index 函數(shù)的返回值。
通過此示例献烦,我們可以看出 Flask 的核心概念包括應(yīng)用對象滓窍、路由和視圖函數(shù)。其中應(yīng)用對象用于啟動 Flask 應(yīng)用程序并管理其配置仿荆、路由贰您、擴展等內(nèi)容;路由用于定義 URL 的映射規(guī)則拢操;視圖函數(shù)則是實現(xiàn)路由的具體處理邏輯锦亦,它接收請求參數(shù)并返回 HTTP 響應(yīng)。
基本概念
應(yīng)用對象
Flask 應(yīng)用程序的主體是應(yīng)用對象(Flask 類的實例化對象)令境。應(yīng)用對象包含了所有執(zhí)行 Flask 應(yīng)用程序所需的主要構(gòu)件杠园,例如:
- 路由
- 模板和靜態(tài)文件管理
- 配置
- 上下文管理
- 擴展和中間件等等
通過應(yīng)用對象,我們可以啟動和配置 Flask 應(yīng)用程序舔庶,如下所示:
from flask import Flask
app = Flask(__name__)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=True)
在 Flask 應(yīng)用程序中抛蚁,只有一個應(yīng)用對象,名稱一般設(shè)為 app惕橙。在上面的代碼示例中瞧甩,使用 Flask 類創(chuàng)建了應(yīng)用對象 app,并通過 app.run() 方法啟動 Flask 應(yīng)用程序弥鹦。該方法有多個參數(shù)肚逸,可以指定監(jiān)聽的 IP 地址、端口號和調(diào)試模式等彬坏。
路由
路由決定了 Flask 應(yīng)用程序如何響應(yīng)瀏覽器發(fā)起的請求朦促。在 Flask 應(yīng)用程序中,可以通過 Flask 類的 route 裝飾器為應(yīng)用程序關(guān)聯(lián) URL:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello World!'
if __name__ == '__main__':
app.run()
在上面的代碼示例中栓始,使用 @app.route('/') 裝飾器將根 URL 綁定到了 hello 函數(shù)务冕。當瀏覽器訪問根 URL 時,F(xiàn)lask 會自動調(diào)用該函數(shù)幻赚,并將它的返回值(Hello World!)作為 HTTP 響應(yīng)返回給瀏覽器禀忆。此外,對于非根 URL坯屿,可以通過在裝飾器中指定 URL 路徑的方式進行綁定:
@app.route('/users')
def show_users():
return 'All users'
這樣定義后油湖,訪問 /users URL 時,F(xiàn)lask 會自動調(diào)用 show_users 函數(shù)领跛,并將它的返回值作為 HTTP 響應(yīng)返回給瀏覽器乏德。
視圖函數(shù)
視圖函數(shù)是 Flask 應(yīng)用程序中接收和處理請求的路由處理函數(shù)。在 Flask 應(yīng)用程序中,可以通過定義視圖函數(shù)來響應(yīng) HTTP 請求和生成相應(yīng)的 HTTP 響應(yīng)喊括。
@app.route('/books/<book_id>')
def show_book(book_id):
return 'Book %s' % book_id
例如上述 show_book 函數(shù)胧瓜,使用變量 <book_id> 指定了 URL 動態(tài)參數(shù),F(xiàn)lask 會自動解析請求 URL郑什,并將其中的參數(shù)傳遞給 show_book 函數(shù)府喳。在函數(shù)內(nèi)部,可以使用傳入的參數(shù)生成相應(yīng)的 HTTP 響應(yīng)蘑拯,例如上述函數(shù)返回 'Book %s' % book_id钝满,其中 %s 用于占位符,將被傳入的 book_id 取代申窘。
請求和響應(yīng)對象
在 Flask 中弯蚜,請求和響應(yīng)都是對象。請求對象表示客戶端發(fā)送給服務(wù)器的 HTTP 請求剃法,可以包含請求的 URL碎捺、請求參數(shù)、請求方法贷洲、請求頭等信息收厨。響應(yīng)對象表示服務(wù)器向客戶端回送的 HTTP 響應(yīng),可以包含響應(yīng)狀態(tài)碼优构、響應(yīng)頭诵叁、響應(yīng)正文等信息。
在 Flask 中钦椭,可以使用 request 對象和 response 對象來訪問和操作請求和響應(yīng)對象黎休。例如,在視圖函數(shù)中可以通過 request 對象獲取請求參數(shù)玉凯,通過 response 對象設(shè)置響應(yīng)頭和響應(yīng)正文:
from flask import Flask, request, make_response
@app.route('/books')
def show_books():
title = request.args.get('title', '')
author = request.args.get('author', '')
return 'Book search: title=%s, author=%s' % (title, author)
@app.route('/download')
def download():
filename = 'sample.pdf'
response = make_response(open(filename, 'rb').read())
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
在上述代碼中,show_books 函數(shù)使用 request 對象獲取名為 title 和 author 的請求參數(shù)联贩,并返回字符串 'Book search: title=%s, author=%s' % (title, author)漫仆。而 download 函數(shù)則創(chuàng)建了一個 response 對象,設(shè)置了文件內(nèi)容和響應(yīng)頭泪幌,并將該對象作為 HTTP 響應(yīng)返回給客戶端盲厌。
模板
在 Flask 應(yīng)用程序中,可以通過 Jinja2 模板引擎渲染動態(tài)的 HTML 頁面祸泪。Jinja2 提供了一套簡單易用的模板語言吗浩,可以輕松嵌入 Python 代碼和變量,并支持循環(huán)没隘、條件語句懂扼、過濾器等。
為了使用 Jinja2 模板引擎,需要為 Flask 應(yīng)用程序指定一個存放模板文件的文件夾阀湿。在 Flask 中赶熟,可以通過 app 對象的 template_folder 屬性來指定模板文件夾:
from flask import Flask, render_template
app = Flask(__name__, template_folder='templates')
@app.route('/')
def show_index():
return render_template('index.html')
@app.route('/books/<book_id>')
def show_book(book_id):
return render_template('book.html', book_id=book_id)
在定義視圖函數(shù)時,通過 render_template 函數(shù)加載模板并生成 HTML 頁面陷嘴。該函數(shù)的第一個參數(shù)為模板文件名映砖,后面的參數(shù)則用于指定模板中需要渲染的變量。例如灾挨,上述 show_index 函數(shù)和 show_book 函數(shù)分別將 index.html 模板和 book.html 模板渲染成 HTML 頁面邑退,并將它們作為 HTTP 響應(yīng)返回給客戶端。
Flask 框架支持多種模板文件格式劳澄,例如 HTML地技、XML、JSON浴骂、CSS乓土、JavaScript 等。Jinja2 也提供了豐富的過濾器和控制結(jié)構(gòu)溯警,例如 if-else 語句趣苏、for 循環(huán)、宏等梯轻,讓開發(fā)者可以靈活地處理模板數(shù)據(jù)食磕。
配置
在 Flask 應(yīng)用程序中,可以通過 app.config 字典存儲和管理應(yīng)用程序的各種配置喳挑。Flask 框架提供了一些常見的配置選項彬伦,并支持從 Python 代碼、環(huán)境變量伊诵、INI 文件单绑、JSON 文件等多種來源讀取配置。
from flask import Flask, render_template
app = Flask(__name__)
app.config["DEBUG"] = True
@app.route('/')
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run()
在上述代碼中曹宴,通過 app.config 字典設(shè)置了 DEBUG 配置選項為 True搂橙。該選項用于啟用 Flask 的調(diào)試模式,可以在代碼修改后自動重載應(yīng)用程序笛坦,方便開發(fā)者進行調(diào)試和測試区转。
Flask 中還支持使用
app.config.from_envvar('CONFIG_FILE')
來自動從環(huán)境變量中加載配置文件。例如版扩,我們可以在服務(wù)器的環(huán)境變量中設(shè)置 CONFIG_FILE 變量废离,并指定為一個 JSON 文件的路徑,那么 Flask 將會自動加載這個 JSON 文件并將其中的配置項應(yīng)用到應(yīng)用程序中礁芦。
擴展
Flask 框架的靈活性和可定制性得益于它豐富的擴展庫蜻韭。Flask 的擴展庫提供了大量功能強大、易于使用的組件和工具,可以幫助開發(fā)者快速實現(xiàn)各種功能需求湘捎,例如郵件發(fā)送诀豁、數(shù)據(jù)庫操作、表單驗證窥妇、用戶認證等等舷胜。
以下是一些常用的 Flask 擴展庫和其基本使用方法:
- Flask-SQLAlchemy:SQLAlchemy 是一個強大的對象關(guān)系映射庫,在 Flask 應(yīng)用程序中活翩,可以使用 Flask-SQLAlchemy 擴展來管理和操作數(shù)據(jù)庫烹骨。基本使用方法:
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
def __repr__(self):
return '<User %r>' % self.username
- Flask-Mail:Flask-Mail 擴展提供了郵件發(fā)送功能材泄,可以方便地構(gòu)造郵件沮焕、發(fā)送郵件和處理郵件回復(fù)等±冢基本使用方法:
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'your-gmail-username'
app.config['MAIL_PASSWORD'] = 'your-gmail-password'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app)
@app.route('/')
def send_email():
msg = Message('Hi', recipients=['recipient@example.com'])
msg.body = 'This is a test email from Flask'
mail.send(msg)
return 'Email sent'
if __name__ == '__main__':
app.run()
- Flask-WTF:Flask-WTF 擴展提供了表單驗證峦树、字段渲染、驗證錯誤等功能旦事】基本使用方法:
from flask import Flask, render_template, request
from wtforms import Form, StringField, SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret-key'
class SearchForm(Form):
query = StringField('Search', render_kw={"placeholder": "Keyword"})
submit = SubmitField('Search')
@app.route('/', methods=['GET', 'POST'])
def search():
form = SearchForm(request.form)
if request.method == 'POST' and form.validate():
return 'Search keyword: %s' % form.query.data
return render_template('search.html', form=form)
if __name__ == '__main__':
app.run()
Flask 還有許多其他擴展庫,例如 Flask-Login姐浮、Flask-Redis谷遂、Flask-JWT 等,在實際開發(fā)中可以根據(jù)需要選擇合適的擴展卖鲤。
示例代碼
以下是一個使用 Flask 和 Bootstrap 實現(xiàn)的待辦事項 Web 應(yīng)用程序的示例代碼:
from flask import Flask, render_template, request, redirect, url_for
from flask_bootstrap import Bootstrap
import os
app = Flask(__name__)
Bootstrap(app)
TODO_FILE = 'todo.txt'
if not os.path.exists(TODO_FILE):
with open(TODO_FILE, 'w') as f:
pass
def read_todo_file():
with open(TODO_FILE, 'rt') as f:
return f.readlines()
def write_todo_file(todos):
with open(TODO_FILE, 'wt') as f:
f.writelines(todos)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
add_todo = request.form['add-todo']
todos = read_todo_file()
todos.append(add_todo + '\n')
write_todo_file(todos)
todos = read_todo_file()
return render_template('index.html', todos=todos)
@app.route('/delete/<int:index>')
def delete(index):
todos = read_todo_file()
del todos[index]
write_todo_file(todos)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run()
該應(yīng)用程序包含了一個待辦事項列表肾扰,用戶可以添加新的待辦事項和刪除已有的待辦事項。在實現(xiàn)時蛋逾,通過讀寫文本文件的方式存儲和操作待辦事項集晚,調(diào)用了 Flask 提供的模板和路由等基本功能,并引入了 Bootstrap 擴展庫提供的樣式和組件区匣。