【问题标题】:How to import blueprints with the same name as the file they are in?如何导入与其所在文件同名的蓝图?
【发布时间】:2019-03-24 15:34:09
【问题描述】:

背景

我正在尝试设置一个名称与它所在的文件名匹配的蓝图,这样当我在app.py 中引用它时,我就知道蓝图的来源。这应该是可能的,因为exploreflask 上的示例使用了相同的模式。尽管如此,我还是无法弄清楚如何使用我的结构来完成这项工作。

文件结构

├── app.py
├── frontend
    ├── __init__.py
    └── views
        ├── home.py
        └── __init__.py

示例

frontend/views/home.py

from flask import Blueprint, render_template

home = Blueprint('home', __name__)
home1 = Blueprint('home1', __name__)

前端/视图/__init__.py

from .home import home
from .home import home1

app.py

from flask import Flask

from frontend.views import home
from frontend.views import home1

print (type(home))  --> <class 'function'> 
print (type(home1)) --> <class 'flask.blueprints.Blueprint'>

由于home1 正确注册为Blueprinthome 我不怀疑 有名称冲突,但我不知道如何解决它,尽管调查 this excellent article 关于导入约定。

因此,当我尝试在应用中注册我的蓝图时 这将起作用:

app.register_blueprint(home1, url_prefix='/home1') --> Fine

但这不会:

app.register_blueprint(home, url_prefix='/home')
--> AttributeError: 'function' object has no attribute 'name'

为什么不直接使用 home1 呢?

  1. 我想了解如何解决冲突
  2. 我希望能够使用与它们所在的文件名相同的路由名称,如下所示:

frontend/views/home.py

from flask import Blueprint, render_template

home = Blueprint('home', __name__)

@home.route('/')
def home():
  pass

【问题讨论】:

  • 您是否尝试使用exporeflask 中描述的分区或功能结构?

标签: python flask python-import


【解决方案1】:

我认为您的 views/__init__.py 文件导致了这个问题。它使 python 假设您的 home.py 文件是要导入的模块。我相信from frontend.views import home 行正在尝试导入home.py 文件,而不是您想要的home.home 蓝图。

这是一个工作示例:

/app.py

from app import create_app
app = create_app()

if __name__ == '__main__':
    app.run()

/app/__init__.py

from flask import Flask

def create_app():
    app = Flask(__name__) 
    from .bp import bp  
    app.register_blueprint(bp)   
    return app

/app/bp/__init__.py

from flask import Blueprint
bp = Blueprint('bp', __name__, template_folder='templates')
from . import views

/app/bp/views.py

from app.bp import bp

@bp.route('/helloworld')
def helloworld():

    return "hello world"

【讨论】:

    【解决方案2】:

    尝试在蓝图模块中使用大写字母。

    您也可以在模块中使用 url_prefix。

    Home = Blueprint("Home", __name__, url_prefix="/home")
    
    @Home.route("/")
    def home():
        pass
    

    【讨论】:

    • 使用大写字母可能是一种棘手的解决方法,但这正是我想要避免的。此外,它还违反了 PEP8:大写字母用于类。 url_prefix 与问题无关(反正我已经在使用它了)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2016-03-04
    • 2018-08-09
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多