【问题标题】:Splitting application.py file into seperate files将 application.py 文件拆分为单独的文件
【发布时间】:2020-07-01 12:45:08
【问题描述】:

我有一个问题,我在我的项目中创建了一个用于创建数据库的命令,我的问题是我想将它和其他类似的东西移动到单独的文件中,但是如果我尝试从不同的文件中导入它们我收到一个导入错误,谁能帮我解决这个问题,谢谢。 这是我的 application.py 文件。

import flask

from database_website.extensions.database import db
from database_website.properties import navigation_bar


class Application(flask.Flask):
    def load_configuration(self):
        self.config.from_pyfile('configuration.py')

    def configure_database(self):
        from database_website.extensions.database import db

        db.init_app(app=self)

    def configure_login_manager(self):
        from database_website.extensions.auth import login_manager

        login_manager.init_app(app=self)

    def register_applications(self):
        from database_website.applications.core.urls import blueprint as core_blueprint
        from database_website.applications.users.urls import blueprint as users_blueprint
        from database_website.applications.products.urls import blueprint as products_blueprint

        self.register_blueprint(blueprint=users_blueprint)
        self.register_blueprint(blueprint=products_blueprint)
        self.register_blueprint(blueprint=core_blueprint)

    @classmethod
    def create(cls):
        instance = Application(__name__)

        instance.load_configuration()
        instance.configure_database()
        instance.configure_login_manager()
        instance.register_applications()

        return instance


application = Application.create()


@application.cli.command()
def create_database():
    db.create_all()


def has_no_empty_params(rule):
    defaults = rule.defaults if rule.defaults is not None else ()
    arguments = rule.arguments if rule.arguments is not None else ()
    return len(defaults) >= len(arguments)


def sitemap():
    links = []
    for rule in application.url_map.iter_rules():
        # Filter out rules we can't navigate to in a browser
        # and rules that require parameters
        if "GET" in rule.methods and has_no_empty_params(rule):
            url = flask.url_for(rule.endpoint, **(rule.defaults or {}))
            links.append((url, rule.endpoint))
    return links


@application.context_processor
def inject_endpoints():
    return dict(endpoints=sitemap())


@application.context_processor
def inject_navigation():
    return dict(nav_bar=navigation_bar)


application.run()

我想要移动的东西是注入和命令。

编辑命令并将命令移动到 commands.py 文件后,我的 application.py 文件。

mport flask

from flask_migrate import Migrate

from database_website.extensions.database import db
from database_website.properties import navigation_bar
from database_website.commands import create_database


class Application(flask.Flask):
    def create_migrations(self):
        migrate = Migrate(self, db)

    def load_configuration(self):
        self.config.from_pyfile('configuration.py')

    def configure_database(self):
        from database_website.extensions.database import db

        db.init_app(app=self)

    def configure_login_manager(self):
        from database_website.extensions.auth import login_manager

        login_manager.init_app(app=self)

    def register_applications(self):
        from database_website.applications.core.urls import blueprint as core_blueprint
        from database_website.applications.users.urls import blueprint as users_blueprint
        from database_website.applications.products.urls import blueprint as products_blueprint

        self.register_blueprint(blueprint=users_blueprint)
        self.register_blueprint(blueprint=products_blueprint)
        self.register_blueprint(blueprint=core_blueprint)

    @classmethod
    def create(cls):
        instance = Application(__name__)

        instance.load_configuration()
        instance.configure_database()
        instance.configure_login_manager()
        instance.register_applications()
        instance.create_migrations()

        return instance


application = Application.create()


def has_no_empty_params(rule):
    defaults = rule.defaults if rule.defaults is not None else ()
    arguments = rule.arguments if rule.arguments is not None else ()
    return len(defaults) >= len(arguments)


def sitemap():
    links = []
    for rule in application.url_map.iter_rules():
        # Filter out rules we can't navigate to in a browser
        # and rules that require parameters
        if "GET" in rule.methods and has_no_empty_params(rule):
            url = flask.url_for(rule.endpoint, **(rule.defaults or {}))
            links.append((url, rule.endpoint))
    return links


@application.context_processor
def inject_endpoints():
    return dict(endpoints=sitemap())


@application.context_processor
def inject_navigation():
    return dict(nav_bar=navigation_bar)


application.run()

回溯:

Traceback (most recent call last):
  File "C:\Users\ulman\PycharmProjects\database_website_optimised\source\database_website\application.py", line 7, in <module>
    from database_website.commands import create_database
  File "C:\Users\ulman\PycharmProjects\database_website_optimised\source\database_website\commands.py", line 1, in <module>
    from database_website.application import application
  File "C:\Users\ulman\PycharmProjects\database_website_optimised\source\database_website\application.py", line 7, in <module>
    from database_website.commands import create_database
ImportError: cannot import name 'create_database' from 'database_website.commands' (C:\Users\ulman\PycharmProjects\database_website_optimised\source\database_website\commands.py)

我将命令移至命令文件,然后将其导入应用程序文件。

【问题讨论】:

    标签: python python-3.x flask


    【解决方案1】:

    已编辑:

    我自己没有运行过此程序,但类似这样的内容应该为您指明正确的方向。您应该能够像您已经注册的其他蓝图一样注册您的命令蓝图。

    commands.py

    from flask import Blueprint
    
    from database_website.extensions.database import db
    
    blueprint = Blueprint('commands_blueprint', __name__)
    
    @commands_blueprint.cli.command()
    def create_database():
        db.create_all()
    

    applications.py

    import flask
    
    from database_website.extensions.database import db
    from database_website.properties import navigation_bar
    
    class Application(flask.Flask):
        ...
        def register_applications(self):
            from database_website.applications.core.urls import blueprint as core_blueprint
            from database_website.applications.users.urls import blueprint as users_blueprint
            from database_website.applications.products.urls import blueprint as products_blueprint
            from database_wensite.commands import blueprint as commands_blueprint
    
            self.register_blueprint(blueprint=users_blueprint)
            self.register_blueprint(blueprint=products_blueprint)
            self.register_blueprint(blueprint=core_blueprint)
            self.register_blueprint(blueprint=commands_blueprint)
        ...
    
    

    您可以使用烧瓶蓝图来帮助您的代码更加模块化。

    https://flask.palletsprojects.com/en/1.1.x/blueprints/

    Where should I implement flask custom commands (cli)

    【讨论】:

    • 我正在使用蓝图,但如果我理解正确,我可以在蓝图中创建 cli 命令吗?(但在我的情况下,create-database 命令不是特定于蓝图)
    • 你的代码在你重构之后是什么样子的,你收到了什么错误?
    • 将添加到我的编辑中,编辑:添加到我的原始帖子中,方式很笨拙,但如果不重新导入它就不会被阅读。你提到了蓝图,那么我可以为命令创建一个“命令”蓝图吗?或者也许有更好的方法
    • 我已经更新了我的答案,请尝试注册您的命令蓝图,就像您注册任何其他蓝图一样。注意:我不知道您的项目文件夹结构,因此请注意导入
    • Upadte,在某处找到了我的问题的答案,结果证明我应该使用 app_context_Processor 而不是 context_Processor
    猜你喜欢
    • 1970-01-01
    • 2016-02-07
    • 2015-05-25
    • 1970-01-01
    • 2018-06-24
    • 2020-01-12
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多