Flask 框架学习文档
概述
Flask 是一个使用 Python 编写的 Web 框架。它的设计目标是简单、轻量级、易扩展,并且具有良好的灵活性和可定制性。Flask 提供了基本的路由、请求处理、模板渲染、Cookie 管理等功能,同时也可以借助丰富的扩展库来实现更加复杂的功能。Flask 尤其适用于开发小型 Web 应用、API 和原型系统等。
Flask 使用基于 Werkzeug 和 Jinja2 的内核,其中 Werkzeug 提供了 HTTP 协议相关的基础功能,如 HTTP 服务器、请求响应处理、URL 路由等,而 Jinja2 提供了模板渲染机制。Flask 本身只提供了这两个基础依赖的封装,并且易于扩展。
安装和使用
使用 Flask 前需要安装 Python 环境,并通过 pip 安装 Flask 库。安装完成后,我们可以编写简单的 Flask 应用程序:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello world!'
if __name__ == '__main__':
app.run()
运行该脚本,Flask 就会在本地启动一个 HTTP 服务器,监听默认端口 5000,并提供一个 URL 为 / 的路由,当用户访问该 URL 时,会返回一个字符串 “Hello world!”,即 index 函数的返回值。
通过此示例,我们可以看出 Flask 的核心概念包括应用对象、路由和视图函数。其中应用对象用于启动 Flask 应用程序并管理其配置、路由、扩展等内容;路由用于定义 URL 的映射规则;视图函数则是实现路由的具体处理逻辑,它接收请求参数并返回 HTTP 响应。
基本概念
应用对象
Flask 应用程序的主体是应用对象(Flask 类的实例化对象)。应用对象包含了所有执行 Flask 应用程序所需的主要构件,例如:
- 路由
- 模板和静态文件管理
- 配置
- 上下文管理
- 扩展和中间件等等
通过应用对象,我们可以启动和配置 Flask 应用程序,如下所示:
from flask import Flask
app = Flask(__name__)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=True)
在 Flask 应用程序中,只有一个应用对象,名称一般设为 app。在上面的代码示例中,使用 Flask 类创建了应用对象 app,并通过 app.run() 方法启动 Flask 应用程序。该方法有多个参数,可以指定监听的 IP 地址、端口号和调试模式等。
路由
路由决定了 Flask 应用程序如何响应浏览器发起的请求。在 Flask 应用程序中,可以通过 Flask 类的 route 装饰器为应用程序关联 URL:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello World!'
if __name__ == '__main__':
app.run()
在上面的代码示例中,使用 @app.route('/') 装饰器将根 URL 绑定到了 hello 函数。当浏览器访问根 URL 时,Flask 会自动调用该函数,并将它的返回值(Hello World!)作为 HTTP 响应返回给浏览器。此外,对于非根 URL,可以通过在装饰器中指定 URL 路径的方式进行绑定:
@app.route('/users')
def show_users():
return 'All users'
这样定义后,访问 /users URL 时,Flask 会自动调用 show_users 函数,并将它的返回值作为 HTTP 响应返回给浏览器。
视图函数
视图函数是 Flask 应用程序中接收和处理请求的路由处理函数。在 Flask 应用程序中,可以通过定义视图函数来响应 HTTP 请求和生成相应的 HTTP 响应。
@app.route('/books/<book_id>')
def show_book(book_id):
return 'Book %s' % book_id
例如上述 show_book 函数,使用变量 <book_id> 指定了 URL 动态参数,Flask 会自动解析请求 URL,并将其中的参数传递给 show_book 函数。在函数内部,可以使用传入的参数生成相应的 HTTP 响应,例如上述函数返回 'Book %s' % book_id,其中 %s 用于占位符,将被传入的 book_id 取代。
请求和响应对象
在 Flask 中,请求和响应都是对象。请求对象表示客户端发送给服务器的 HTTP 请求,可以包含请求的 URL、请求参数、请求方法、请求头等信息。响应对象表示服务器向客户端回送的 HTTP 响应,可以包含响应状态码、响应头、响应正文等信息。
在 Flask 中,可以使用 request 对象和 response 对象来访问和操作请求和响应对象。例如,在视图函数中可以通过 request 对象获取请求参数,通过 response 对象设置响应头和响应正文:
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 函数使用 request 对象获取名为 title 和 author 的请求参数,并返回字符串 'Book search: title=%s, author=%s' % (title, author)。而 download 函数则创建了一个 response 对象,设置了文件内容和响应头,并将该对象作为 HTTP 响应返回给客户端。
模板
在 Flask 应用程序中,可以通过 Jinja2 模板引擎渲染动态的 HTML 页面。Jinja2 提供了一套简单易用的模板语言,可以轻松嵌入 Python 代码和变量,并支持循环、条件语句、过滤器等。
为了使用 Jinja2 模板引擎,需要为 Flask 应用程序指定一个存放模板文件的文件夹。在 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)
在定义视图函数时,通过 render_template 函数加载模板并生成 HTML 页面。该函数的第一个参数为模板文件名,后面的参数则用于指定模板中需要渲染的变量。例如,上述 show_index 函数和 show_book 函数分别将 index.html 模板和 book.html 模板渲染成 HTML 页面,并将它们作为 HTTP 响应返回给客户端。
Flask 框架支持多种模板文件格式,例如 HTML、XML、JSON、CSS、JavaScript 等。Jinja2 也提供了丰富的过滤器和控制结构,例如 if-else 语句、for 循环、宏等,让开发者可以灵活地处理模板数据。
配置
在 Flask 应用程序中,可以通过 app.config 字典存储和管理应用程序的各种配置。Flask 框架提供了一些常见的配置选项,并支持从 Python 代码、环境变量、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 字典设置了 DEBUG 配置选项为 True。该选项用于启用 Flask 的调试模式,可以在代码修改后自动重载应用程序,方便开发者进行调试和测试。
Flask 中还支持使用
app.config.from_envvar('CONFIG_FILE')
来自动从环境变量中加载配置文件。例如,我们可以在服务器的环境变量中设置 CONFIG_FILE 变量,并指定为一个 JSON 文件的路径,那么 Flask 将会自动加载这个 JSON 文件并将其中的配置项应用到应用程序中。
扩展
Flask 框架的灵活性和可定制性得益于它丰富的扩展库。Flask 的扩展库提供了大量功能强大、易于使用的组件和工具,可以帮助开发者快速实现各种功能需求,例如邮件发送、数据库操作、表单验证、用户认证等等。
以下是一些常用的 Flask 扩展库和其基本使用方法:
- Flask-SQLAlchemy:SQLAlchemy 是一个强大的对象关系映射库,在 Flask 应用程序中,可以使用 Flask-SQLAlchemy 扩展来管理和操作数据库。基本使用方法:
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 扩展提供了邮件发送功能,可以方便地构造邮件、发送邮件和处理邮件回复等。基本使用方法:
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 等,在实际开发中可以根据需要选择合适的扩展。
示例代码
以下是一个使用 Flask 和 Bootstrap 实现的待办事项 Web 应用程序的示例代码:
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()
该应用程序包含了一个待办事项列表,用户可以添加新的待办事项和删除已有的待办事项。在实现时,通过读写文本文件的方式存储和操作待办事项,调用了 Flask 提供的模板和路由等基本功能,并引入了 Bootstrap 扩展库提供的样式和组件。
网友评论