21

在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,所以我必须将 appcommands.py导入并导入我的命令app.py导致循环导入错误。

如何在单独的文件中创建自定义命令?

4

5 回答 5

26

实现这一目标的一种方法是使用蓝图

我已经使用 Flask 1.1.1 对其进行了测试,因此请务必检查您拥有的正确版本的文档。

这是一般的想法:

  1. 在不同的文件中创建一个或多个蓝图,假设它被称为 commands.py
  2. 然后导入新的蓝图并将它们注册到您的应用程序

==> 应用程序.py <==

from flask import Flask
from commands import usersbp

app = Flask(__name__)
# you MUST register the blueprint
app.register_blueprint(usersbp)

==> commands.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
于 2019-10-07T20:50:04.350 回答
6

只需将其导入您的应用工厂

dir tree

my_app
     L app.py
     L commands.py

命令.py

@app.cli.command('resetdb')
def resetdb_command():
    """Here info that will be shown in flask --help"""
    pass

应用程序.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

但必须有更好的方法;)我现在不知道

于 2020-02-21T09:59:13.147 回答
2

如果您使用的是应用程序工厂(您有一个create_app()函数),那么app您甚至没有要导入的变量。

保持代码井井有条的最佳方法是在其他地方定义函数,然后在构建应用程序实例时注册它。

例如

my_app/
 | main.py
 | app/
 |  | __init__.py
 |  | commands.py

命令.py

def foo():
   print("Running foo()")

初始化.py

def create_app():
 app = Flask(__name__)
 ...
 from .commands import foo
 @app.cli.command('foo')
 def foo_command():
   foo()
 ...
于 2021-04-02T19:43:49.610 回答
2

如果您不使用应用工厂模式,什么对我有用,类似于@quester:

应用程序.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 *

命令.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')
于 2021-01-13T21:45:00.930 回答
1

我有这个布局:

基础应用程序.py

from flask import Flask

app = Flask("CmdAttempt")

应用程序.py

from .baseapp import app

def main():
    app.run(
        port=5522,
        load_dotenv=True,
        debug=True
    )

if __name__ == '__main__':
    main()

命令.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_APPto 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
于 2020-04-18T07:42:25.320 回答