在flask中创建自定义命令需要访问该应用,该应用通常在app.py
中创建,如下所示:
import click
from flask import Flask
app = Flask(__name__)
@app.cli.command("create-user")
@click.argument("name")
def create_user(name):
...
但是,为了不肿我的app.py,我想将自定义命令放在一个单独的文件中,例如commands.py
,但这不起作用,因为我项目的入口点是app.py
,所以我必须在commands.py
中导入应用程序,并在app.py
中导入命令导致循环导入错误。
如何在单独的文件中创建自定义命令?
答案 0 :(得分:5)
只需将其导入您的应用程序工厂
dir tree
my_app
L app.py
L commands.py
commands.py
@app.cli.command('resetdb')
def resetdb_command():
"""Here info that will be shown in flask --help"""
pass
app.py
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URL
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
with app.app_context():
from . import routes
from . import commands # <----- here
return app
$ export FLASK_APP=my_app/app.py
$ flask resetdb
但是必须有更好的方法;)我现在还不知道
答案 1 :(得分:3)
一种实现此目标的方法是使用blueprints
我已经使用Flask 1.1.1对其进行了测试,因此请务必检查您拥有的正确版本的文档。
这是一般想法:
==> app.py <==
from flask import Flask
from commands import usersbp
app = Flask(__name__)
# you MUST register the blueprint
app.register_blueprint(usersbp)
==>命令。py<==
import click
from flask import Blueprint
usersbp = Blueprint('users', __name__)
@usersbp.cli.command('create')
@click.argument('name')
def create(name):
""" Creates a user """
print("Create user: {}".format(name))
执行flask users
后,您应该得到如下响应:
flask users
Usage: flask users [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
create Creates a user
答案 2 :(得分:1)
我有这样的布局:
baseapp.py
from flask import Flask
app = Flask("CmdAttempt")
app.py
from .baseapp import app
def main():
app.run(
port=5522,
load_dotenv=True,
debug=True
)
if __name__ == '__main__':
main()
commands.py
import click
from .baseapp import app
@app.cli.command("create-super-user")
@click.argument("name")
def create_super_user(name):
print("Now creating user", name)
if __name__ == '__main__':
from .app import main
main()
在运行命令的控制台中,首先将FLASK_APP
定义为commands.py
,然后运行定义的命令。
set FLASK_APP=commands.py
export FLASK_APP=commands.py
flask create-super-user me
您可以对内置命令使用单独的终端,也可以在发出命令之前清除FLASK_APP
变量。在Linux中甚至更容易,因为您可以做到
FLASK_APP=commands.py flask create-super-user me
答案 3 :(得分:1)
如果您没有使用类似于@quester 的应用工厂模式,什么对我有用:
app.py
import os
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv("DATABASE_URL")
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
migrate = Migrate(app, db)
with app.app_context():
# needed to make CLI commands work
from commands import *
commands.py
from app import app
@app.cli.command()
def do_something():
print('hello i am so nice I posted this even though I have 100 other things to do')
答案 4 :(得分:1)
如果您使用的是应用工厂(您有一个 create_app()
函数),那么甚至没有一个 app
变量可供您导入。
保持代码井井有条的最好方法是在其他地方定义函数,然后在构建应用程序实例时注册它。
例如
my_app/
| main.py
| app/
| | __init__.py
| | commands.py
commands.py
def foo():
print("Running foo()")
init.py
def create_app():
app = Flask(__name__)
...
from .commands import foo
@app.cli.command('foo')
def foo_command():
foo()
...