Flask框架提供了灵活的方式来通过终端命令行管理项目,但不同版本之间存在差异。本文将系统梳理Flask 1.0(使用Flask-Script)与Flask 2.0+(使用内置Click)两个时代的终端命令使用方法,并演示如何自定义实用的命令行工具。
终端脚本命令演进
在Flask 0.11版本之前,开发者依赖flask-script这个第三方模块来实现终端脚本命令。由于兼容性问题,Flask从0.11版本开始,内置了Click模块来接管此项功能,提供了更现代化的命令行交互体验。
Flask 1.0时代的终端命令使用
注意:Python 3.9及以上版本已不再支持Flask 1.x系列。如需运行Flask 1,需要安装Python 3.8或以下版本。
flask-script模块允许我们通过终端控制Flask项目的运行,其角色类似于Django的manage.py。
安装与基本使用
首先,创建一个Python 3.8环境并安装所需依赖:
conda create -n py38 python=3.8
conda activate py38
pip install -U flask==1.1.4
pip install -U flask-script -i https://pypi.douban.com/simple
接着,将Flask-Script集成到应用中。通常我们会创建一个名为manage.py(或run.py、main.py)的主程序文件:
from flask import Flask
app = Flask(__name__)
"""使用flask_script启动项目"""
from flask_script import Manager
manager = Manager(app)
@app.route('/')
def index():
return 'hello world'
if __name__ == "__main__":
manager.run()
启动项目的基本命令如下:
# 使用默认地址127.0.0.1和端口5000
python manage.py runserver
# 通过-h设置启动域名,-p设置启动端口
python manage.py runserver -h0.0.0.0 -p8888 # 关闭debug模式
python manage.py runserver -h0.0.0.0 -p8888 -d # 开启debug模式
# 进入flask交互终端,可直接调用flask代码进行测试
python manage.py shell
故障排除:安装Flask 1.1.4启动时,若出现错误 from markupsafe import soft_unicode,找到报错文件位置,将导入语句修改为:
from markupsafe import soft_str as soft_unicode
自定义终端命令
Flask-Script允许为应用程序添加自定义脚本命令。
- 引入
Command命令基类。
- 创建的命令类必须直接或间接继承
Command,并实现run或__call__方法。如需自定义参数,需实现get_options方法或设置option_list属性。
- 使用应用管理器
manager.add_command注册命令类并设置调用别名。
以下是一个完整的自定义命令示例(manage.py):
from flask import Flask
app = Flask(__name__)
"""使用flask_script管理项目"""
from flask_script import Manager
manager = Manager(app)
from abc import ABC
from flask_script import Command, Option
class PrintCommand(Command, ABC):
"""
命令的相关描述: 打印数据
"""
def get_options(self):
# 必须返回选项
return (
# Option('简写选项名', '参数选项名', dest='变量名', type=数据类型, default="默认值"),
Option('-h', '--host', dest='host', type=str, default="127.0.0.1"),
Option('-p', '--port', dest='port', type=int, default=8000),
Option('-d', '--debug', dest='debug', type=bool, default=False)
)
# 也可以使用option_list来替代get_options
# option_list = (
# Option('-h', '--host', dest='host', type=str, default="127.0.0.1"),
# Option('-p', '--port', dest='port', type=int, default="7000"),
# Option('-d', '--debug', dest='debug', type=bool, default=False)
# )
def __call__(self, app, host, port, debug): # 会自动传递当前flask实例对象进来
print(f"测试命令,{app}")
print(f"self.host={host}")
print(f"self.port={port}")
print(f"self.debug={debug}")
# manage.add_command("终端命令名称", 命令类)
manager.add_command("print", PrintCommand) # python manage.py print
@app.route("/")
def index():
return "ok"
if __name__ == '__main__':
manager.run()
命令执行效果如下图所示,你可以通过不同的参数组合来调用自定义的print命令:


Flask 2.0+ 版本的终端命令使用
从Flask 0.11.0开始,框架内置了Python的Click模块。到Flask 2.0时,已不再兼容flask-script,全面转向使用Click来管理和自定义终端命令。
安装Flask 2.0+后,环境中会提供一个全局的flask命令。要使用它,必须指定Flask应用实例所在的入口文件。
配置环境变量
在使用flask终端命令前,建议配置两个环境变量(以下配置方式适用于macOS和Linux系统):
# 指定入口文件,开发中入口文件名一般如:app.py, run.py, manage.py
export FLASK_APP=manage.py
# 指定项目环境模式
export FLASK_DEBUG=True # 开发环境,开启DEBUG模式
# export FLASK_DEBUG=False # 生产环境,关闭DEBUG模式

内置命令详解
配置完成后,即可使用Flask内置的多个实用命令。
一个最简单的Flask应用(manage.py)代码如下:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "ok"
if __name__ == '__main__':
app.run()

使用 flask --help 可以查看所有支持的命令:

常用内置命令包括:
使用Click自定义终端命令
Flask 2.0+ 利用Click装饰器,可以非常便捷地自定义终端命令。
案例:创建数据生成命令
假设我们需要一个faker命令来生成测试数据,它接受数据类型、存储位置和生成数量作为参数。
# 自定义终端命令需要导入click
import click
from flask import Flask
app = Flask(__name__)
# 注册command,自定义一个跟在flask后面的命令
@app.cli.command("faker") # 假设这个用于生成测试数据
# faker后面跟的子命令参数,每个子命令名不能一样
@click.argument("data", type=str, default="user") # 位置参数
@click.argument("position", type=str, default="mysql") # 位置参数
# 第一个是参数简写,第二个是详细写全,第三个是函数内部调用的名字,type是类型,default是默认值,help是辅助信息
@click.option("-n", "--number", "number", type=int, default=1, help="生成的数据量。") # 选项参数
# 我们上面自定义的faker,接子命令执行后,要实现的功能,通过下面这个函数来定义
def faker_command(data, position, number):
"""
命令的说明文档:添加测试信息
"""
print("添加测试信息")
print(f"数据类型:data={data}")
print(f"数据类型:position={position}")
print(f"生成数量:number={number}")
@app.route("/")
def index():
return "ok"
if __name__ == '__main__':
app.run()

定义后,使用flask --help可以看到自定义的faker命令已成功注册。

现在可以尝试运行该命令:
- 使用默认参数:
flask faker

- 自定义数据类型:
flask faker teacher

- 使用选项参数指定生成数量:
flask faker teacher -n200

实战案例:仿Django的startapp命令
Django可以通过命令自动创建应用骨架,而Flask没有内置此功能。利用所学的Click知识,我们可以自己实现一个startapp命令。
要求:执行 flask startapp home 后,在当前目录下创建名为home的子应用目录及一系列标准文件。
目标目录结构如下:
home/
├── views.py
├── models.py
├── documents.py
├── ws.py
├── services.py
├── urls.py
└── tests.py

代码实现 (manage.py):
import click, os
from flask import Flask
app = Flask(__name__)
# 配置
app.config.update({
"DEBUG": False
})
@app.cli.command("startapp")
@click.argument("name")
# @click.option('-n', 'name', help='app name')
def startapp(name):
"""生成子模块或子应用"""
if os.path.isdir(name):
print(f"当前{name}目录已存在!请先处理完成以后再创建。")
return
os.mkdir(name)
open(f"{name}/views.py", "w")
open(f"{name}/models.py", "w")
open(f"{name}/documents.py", "w")
open(f"{name}/ws.py", "w")
open(f"{name}/services.py", "w")
open(f"{name}/urls.py", "w")
open(f"{name}/test.py", "w")
print(f"{name}子应用创建完成……")
@app.route("/")
def index():
return "ok"
if __name__ == '__main__':
app.run()

终端调用:
首先,确认startapp命令已成功添加。

创建名为home的子应用:
flask startapp home

创建完成后,查看生成的文件结构:

同理,可以创建名为users的子应用:
flask startapp users

当然,你可以进一步扩展这个命令,例如在创建文件时预先写入模板代码,使其更加强大和实用。
总结
本文详细对比了Flask 1.0(基于Flask-Script)和Flask 2.0+(基于内置Click)两个版本在终端脚本命令运行方式上的区别与实现。掌握这两种方式,尤其是熟练使用Python的Click库进行程序开发自定义命令,能够极大提升Flask项目的开发和管理效率。希望这篇指南能帮助你在云栈社区的开发之旅中更加得心应手。