Flask

虚拟环境

虚拟环境的使用,可以避免你安装的python版本包与系统预装的发生冲突,为每个项目单独创建虚拟环境,可以保证应用只访问所在虚拟环境中包,从而保持全局解释器的干净整洁。虚拟环境的另一有优点是不需要管理员权限。

虚拟环境的创建

python3

python3的虚拟环境由python标准库中的venv包原生支持,创建虚拟环境的命令格式如下:

1
python3 -m venv venv

-m venv 选项的作用是以独立的脚本运行标准库中的venv包,后面的参数为虚拟环境名称(一般用venv)

python2

python2没有集成venv包,需要使用第三方工具virtualenv创建虚拟环境

Linux或macOS安装virtualenv命令如下:

1
sudo pip install virtualenv

windows下需要以管理员身份执行以下命令:

1
pip install virtualenv

安装完成后进入到相关项目目录下执行以下命令创建虚拟环境:

1
virtualenv venv

虚拟环境的激活

Linux或macOS激活命令如下:(venv为虚拟环境名称)

1
source venv/bin/activate

windows激活命令如下:(venv为虚拟环境名称)

1
venv/Scripts/activate

以上命令需要在与虚拟环境同级目录下执行

Flask

启动web开发服务

flask自带web开发服务,通过

1
flask run

命令启动,这个命令在 FLASK_APP 环境变量中指定的python脚本中寻找应用实例。

以下操作在虚拟环境下执行

Linux或macOS启动web服务器命令如下:

1
2
(venv)$ export FLASK_APP=hello.py
(venv)$ flask run

Windows启动web服务器命令如下:

1
2
(venv)$ set FLASK_APP=hello.py
(venv)$ flask run

调试模式

调试模式默认禁用,若想启用只需在 flask run 命令执行前设定 FLASK_DEBUG=1 环境变量

Linux或macOS环境:

1
2
3
(venv)$ export FLASK_APP=hello.py
(venv)$ export FLASK_DEBUG=1
(venv)$ flask run

Windows环境下:

1
2
3
(venv)$ set FLASK_APP=hello.py
(venv)$ set FLASK_DEBUG=1
(venv)$ flask run

应用和请求上下文

flask上下文全局变量

变量名 上下文 说明
current_app 应用上下文 当前应用的应用实例
g 应用上下文 处理请求时用做临时存储的对象,每次请求都会重设这个变量
request 请求上下文 请求对象,封装了客户端发出的http请求中的内容
session 请求上下文 用户会话,值为一个字典,存储请求之间需要记住的值

flask在分派请求之前激活(或推送)应用和请求上下文,请求处理完成后在将其删除,应用上下文被推送后,就可以在当前线程中使用变量(请求上下文类似)。如果变量没有被激活就使用会导致错误。

请求分派

Flask在收到客户端的请求时,会在应用的URL映射中查找请求的URL, URL映射是URL和视图之间的对应关系,Flask使用app.route装饰器或者使用具有相同作用的方法 app.add_url_rule()构建。

在虚拟环境下可以在 python shell 中查看,如下:

请求对象

Flask通过上下文request对外开发请求对象,包含客户端发送的http请求全部信息,常用的属性方法如下:

属性或方法 说明
form 字典,存储请求提交的所有表单字段
args 字典,存储通过rul查询字符串传递的所有参数
values 字典,forms和args的集合
cookies 字典,存储请求的所有cookie
headers 字典,存储请求的所有http首部
files 字典,存储请求上传的所有文件
get_data() 返回请求主体缓冲的数据
get_json() 返回一个python字典,包含解析主题后得到的json
method 请求方法(post、get等)
scheme url方案(http或者https)
is_secure() 通过安全链接(https)发送的请求返回true
host 主机名,如果有端口号包含端口号
path url路径部分
full_path url路径和查询字符串部分
url 客户端请求的完整url
base_url 同url,没有查询字符串部分
remote_addr 客户端的ip地址

flask 钩子

有时候需要在请求之前需要对用户的身份进行验证等,为了避免重复编写代码,flask提供了钩子方法,Flask支持以下4种请求类型钩子:

方法 说明
before_request 注册一个函数,在每次请求之前运行
before_first_request 注册一个函数,只在第一次请求之前运行,可以添加一些服务器初始化任务
after_request 注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行
teardown_request 注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行

数据库操作

以下操作都在虚拟环境中进行

创建表

首先需要让flask-sqlalchemy根据模型类创建数据库,db.create_all()函数将寻找所有db.Model的子类,然后在数据库中创建对应的表:

1
2
3
(venv)$ flask shelll
>>> from flask import db
>>> db.creaet_all()

Python shell

我们发现,每次启动shell会话都要导入数据库实例和模型,为了避免重复的操作,可以配置成 flask shell 自动导入这些对象。若想把对象添加到导入列表中,必须使用app.shell_context_processor 装饰器创建并注册。

1
2
3
@app.shell_context_processor
def make_shell_context()
return dict(db=db, User=User, Role=Role)

这个shell上下文处理器返回一个字典,除了默认导入到app之外,包含数据库实例和模型。

Flask-Migrate 实现数据库迁移

首先需要在虚拟环境中执行以下命令安装flask-migrate

1
(venv)$ pip install flask-migrate

在项目中初始化flask-migrate,方法如下所示:

这时我们可以使用下面的命令初始化数据库迁移支持,并创建migrations目录,所有迁移脚本都会放在这里

1
(venv)$ flask db init

整个数据库升级操作流程如下所示:

1
2
3
4
1: 对模型类做必要的修改
2: 执行 flask db migrate 命令,自动创建一个迁移脚本
3: 检查生成的脚本,根据模型做实际调整
4: 执行 flask db upgrade 命令,把迁移应用到数据库中

如果在执行 flask db migrate 之后(执行4之前)发现还需对模型作出调整,可以按照如下步骤重新调整:

1
2
3
4
5
1: 使用 flask db downgrade 还原前一个版本的改动
2: 删除前一个迁移脚本
3: 执行 flask db migrate 命令,重新生成一个数据库迁移脚本(这个脚本包含所有修改)
4: 检查生成的脚本,根据模型做实际调整
5: 执行 flask db upgrade 命令,把迁移应用到数据库中

详细命令参考 flask-migrate

需求文件

应用中的requirements.txt 文件,用于记录所有依赖包及其精确的版本号,如果在另一个机器上重新生成虚拟环境,可以直接使用下面命令安装依赖

1
(venv)$ pip install -r requirements.txt

该文件也可以使用下面的命令自动生成:

1
(venv)$ pip freeze ->requirements.txt