Flask 知识介绍
一、核心功能
(一)路由系统
-
定义:通过装饰器将函数绑定到特定的 URL 路径上,当用户访问该 URL 时,对应的函数就会被调用。
-
示例:
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello, World!' @app.route('/about') def about(): return 'This is the about page.'
(二)请求和响应处理
-
请求处理:可以通过
request
对象获取请求的各种信息,如请求方法、参数、表单数据等。 -
响应处理:可以直接返回字符串作为响应,也可以使用
make_response
函数创建更复杂的响应对象。 -
示例:
from flask import request @app.route('/submit', methods=['POST']) def submit(): name = request.form.get('name') return f'Hello, {name}!'
(三)模板引擎
-
使用 Jinja2 模板引擎:可以将动态数据插入到 HTML 模板中,实现页面的动态生成。
-
示例:
-
创建模板文件
index.html
:
<!DOCTYPE html> <html> <head> <title>{{ title }}</title> </head> <body> <h1>Welcome to {{ app_name }}!</h1> </body> </html>
-
Python 代码:
from flask import render_template @app.route('/') def index(): return render_template('index.html', title='Home', app_name='My App')
-
(四)开箱即用的开发服务器和调试器
-
开发服务器:Flask 自带一个轻量级的开发服务器,方便在开发过程中快速测试应用。
-
调试器:在开发模式下,Flask 启用调试器,可以在出现错误时提供详细的错误信息和堆栈跟踪,方便调试。
(五)支持安全性
-
防止跨站请求伪造(CSRF):可以通过使用 Flask-WTF 扩展来添加 CSRF 保护。在表单中添加一个隐藏的 CSRF 令牌,并在提交表单时验证令牌的有效性。
-
示例:
-
安装 Flask-WTF:
pip install Flask-WTF
-
Python 代码:
from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired class NameForm(FlaskForm): name = StringField('What is your name?', validators=[DataRequired()]) submit = SubmitField('Submit') @app.route('/', methods=['GET', 'POST']) def index(): form = NameForm() if form.validate_on_submit(): return f'Hello, {form.name.data}!' return render_template('index.html', form=form)
-
模板文件
index.html
:
<!DOCTYPE html> <html> <head> <title>Flask App</title> </head> <body> <form method="POST"> {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name() }} {{ form.submit() }} </form> </body> </html>
-
二、扩展性
(一)通过扩展增加额外功能
-
Flask-Login:处理用户会话管理,提供用户登录、注销、记住用户等功能。
-
Flask-SQLAlchemy:数据库 ORM(对象关系映射)工具,方便与数据库进行交互。
-
Flask-WTF:表单处理,包括表单验证、CSRF 保护等。
(二)示例(使用 Flask-SQLAlchemy 和 Flask-WTF)
-
安装扩展:
pip install Flask-SQLAlchemy Flask-WTF
-
Python 代码:
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.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) class NameForm(FlaskForm): name = StringField('What is your name?', validators=[DataRequired()]) submit = SubmitField('Submit') @app.route('/', methods=['GET', 'POST']) def index(): form = NameForm() if form.validate_on_submit(): user = User(username=form.name.data) db.session.add(user) db.session.commit() return f'Hello, {form.name.data}! User added to database.' return render_template('index.html', form=form)
-
模板文件
index.html
:
<!DOCTYPE html> <html> <head> <title>Flask App</title> </head> <body> <form method="POST"> {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name() }} {{ form.submit() }} </form> </body> </html>
三、配置和约定
(一)使用配置对象管理应用设置
-
定义:可以通过创建一个配置对象来设置应用的各种参数,如数据库连接字符串、调试模式等。
-
示例:
app = Flask(__name__) class Config: DEBUG = True SQLALCHEMY_DATABASE_URI = 'sqlite:///mydatabase.db' app.config.from_object(Config)
(二)遵循约定
-
静态文件放在 static 文件夹:可以在 HTML 模板中使用
url_for('static', filename='path/to/file')
来引用静态文件。 -
模板文件放在 templates 文件夹:可以使用
render_template('template_name.html',...)
来渲染模板文件。
四、蓝图(Blueprints)
(一)定义
-
蓝图允许开发者在一个应用中组织多个模块化的子应用:每个蓝图可以有自己的路由、模板和静态文件,方便管理大型应用的不同功能模块。
-
示例:
-
创建蓝图:
from flask import Blueprint bp = Blueprint('my_blueprint', __name__) @bp.route('/blueprint_route') def blueprint_function(): return 'This is a route in the blueprint.'
-
在应用中注册蓝图:
app.register_blueprint(bp)
-
五、测试客户端
(一)定义
-
Flask 提供测试客户端:可以模拟 HTTP 请求来测试应用,无需实际启动服务器。
-
示例:
import unittest from flask import Flask from my_app import app class TestApp(unittest.TestCase): def setUp(self): self.app = app.test_client() def test_index(self): response = self.app.get('/') self.assertEqual(response.status_code, 200) self.assertEqual(response.data.decode(), 'Hello, World!') if __name__ == '__main__': unittest.main()
六、命令行接口
(一)定义
-
Flask 带有命令行工具:可以用来初始化项目、运行开发服务器、执行数据库迁移等。
-
示例:
-
创建一个命令行命令:
import click from flask.cli import with_appcontext @click.command('my_command') @with_appcontext def my_command(): print('This is my custom command.')
-
在应用中注册命令:
app.cli.add_command(my_command)
-
在命令行中运行命令:
flask my_command
-
七、上下文
(一)请求上下文和应用程序上下文
-
请求上下文:让开发者能够访问请求特定的变量,如
request
、session
等。 -
应用程序上下文:让开发者能够访问应用全局的变量,如
current_app
、g
等。 -
示例:
from flask import request, current_app @app.route('/') def index(): print(request.method) print(current_app.config['DEBUG']) return 'Hello, World!'
八、错误处理
(一)定制错误页面和错误处理逻辑
-
定义:可以使用
@app.errorhandler
装饰器来定制错误页面和错误处理逻辑。 -
示例:
from flask import render_template @app.errorhandler(404) def page_not_found(e): return render_template('404.html'), 404
九、钩子(Hooks)和信号(Signals)
(一)钩子
-
定义:允许在请求的不同阶段插入自定义代码。
-
示例:
@app.before_request def before_request(): print('Before request') @app.after_request def after_request(response): print('After request') return response
(二)信号
-
定义:是一种在 Flask 扩展中发送和接收通知的方式。
-
示例:
-
安装 Flask-Signals:
pip install Flask-Signals
-
Python 代码:
from flask import Flask from flask_signals import signals app = Flask(__name__) def my_callback(sender, **kwargs): print('Signal received') my_signal = signals.signal('my_signal') my_signal.connect(my_callback) @app.route('/') def index(): my_signal.send(app) return 'Hello, World!'
-
十、安全性
(一)提供安全措施
-
防止跨站请求伪造(CSRF)攻击:除了前面提到的使用 Flask-WTF 扩展来添加 CSRF 保护外,还可以在表单中添加自定义的 CSRF 令牌,并在服务器端进行验证。
-
示例:
-
Python 代码:
from flask import Flask, request, render_template import secrets app = Flask(__name__) app.config['SECRET_KEY'] = secrets.token_hex(16) @app.route('/') def index(): csrf_token = secrets.token_hex(16) return render_template('index.html', csrf_token=csrf_token) @app.route('/submit', methods=['POST']) def submit(): csrf_token = request.form.get('csrf_token') if csrf_token == request.cookies.get('csrf_token'): return 'Form submitted successfully.' else: return 'CSRF token is invalid.', 400
-
模板文件
index.html
:
<!DOCTYPE html> <html> <head> <title>Flask App</title> </head> <body> <form method="POST"> <input type="hidden" name="csrf_token" value="{{ csrf_token }}"> <input type="submit" value="Submit"> </form> </body> </html>
-