Flask詳細學(xué)習(xí)整理(一)

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 擴展庫提供的樣式和組件区匣。

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末甩恼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沉颂,更是在濱河造成了極大的恐慌,老刑警劉巖悦污,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铸屉,死亡現(xiàn)場離奇詭異,居然都是意外死亡切端,警方通過查閱死者的電腦和手機彻坛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昌屉,你說我怎么就攤上這事钙蒙。” “怎么了间驮?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵躬厌,是天一觀的道長。 經(jīng)常有香客問我竞帽,道長扛施,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任屹篓,我火速辦了婚禮疙渣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堆巧。我一直安慰自己妄荔,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布谍肤。 她就那樣靜靜地躺著啦租,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谣沸。 梳的紋絲不亂的頭發(fā)上刷钢,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音乳附,去河邊找鬼内地。 笑死,一個胖子當著我的面吹牛赋除,可吹牛的內(nèi)容都是我干的阱缓。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼举农,長吁一口氣:“原來是場噩夢啊……” “哼荆针!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起颁糟,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤航背,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后棱貌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玖媚,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年婚脱,在試婚紗的時候發(fā)現(xiàn)自己被綠了今魔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勺像。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖错森,靈堂內(nèi)的尸體忽然破棺而出吟宦,到底是詐尸還是另有隱情,我是刑警寧澤涩维,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布殃姓,位于F島的核電站,受9級特大地震影響激挪,放射性物質(zhì)發(fā)生泄漏辰狡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一垄分、第九天 我趴在偏房一處隱蔽的房頂上張望宛篇。 院中可真熱鬧,春花似錦薄湿、人聲如沸叫倍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吆倦。三九已至,卻和暖如春坐求,著一層夾襖步出監(jiān)牢的瞬間蚕泽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工桥嗤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留须妻,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓泛领,卻偏偏與公主長得像荒吏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子渊鞋,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容