Python 烧瓶蓝图初始化-初始化一些全局变量

Python 烧瓶蓝图初始化-初始化一些全局变量,python,flask,blueprint,Python,Flask,Blueprint,我是Flask的新手,我将要编写一个更大的应用程序。到目前为止,我已经将功能划分为蓝图。现在,我希望能够在blueprint初始化期间(在请求上下文之外)从blueprint中设置一些全局变量。基本上,我想为某些蓝图自动初始化导航列表,因此每个蓝图都需要告诉我的基础应用程序它希望如何命名以及它的默认路径是什么 我的目标是,其他人只需将他们的自定义蓝图放入我的应用程序的“插件”文件夹,就可以扩展我的应用程序。在这种情况下,我的应用程序不知道它们的路由或名称。它需要在加载特定蓝图时自动学习它 用另一

我是Flask的新手,我将要编写一个更大的应用程序。到目前为止,我已经将功能划分为蓝图。现在,我希望能够在blueprint初始化期间(在请求上下文之外)从blueprint中设置一些全局变量。基本上,我想为某些蓝图自动初始化导航列表,因此每个蓝图都需要告诉我的基础应用程序它希望如何命名以及它的默认路径是什么

我的目标是,其他人只需将他们的自定义蓝图放入我的应用程序的“插件”文件夹,就可以扩展我的应用程序。在这种情况下,我的应用程序不知道它们的路由或名称。它需要在加载特定蓝图时自动学习它

用另一种方式来解释:我有一个主应用程序,其中包含一些作为蓝图实现的子应用程序。主应用程序应该有一个导航栏,引用所有子应用程序(蓝图)。蓝图如何在主菜单导航变量中注册某些内容(例如初始化)

(我没有找到从蓝图中访问“self.parent”之类的内容或应用程序上下文的方法。难道蓝图没有构造函数之类的内容吗?)

因此,每个蓝图都需要告诉我的基础应用程序它想要的是什么 被命名和它的默认路线是什么

创建蓝图时,已在第一个参数中传递其名称:

simple_page = Blueprint('simple_page')
您也可以将url\u前缀值传递给构造函数

simple_page = Blueprint('simple_page', url_prefix='/pages')
我有一个主应用程序,其中包含一些实现的子应用程序 作为蓝图。主应用程序应该有一个导航栏 引用所有子应用程序(蓝图)

这是一个python模块中的一个示例,您应该将每个蓝图拆分为自己的模块

from flask import Flask, Blueprint, render_template

# ADMIN
admin = Blueprint('admin', __name__, url_prefix='/admin')

@admin.route('/')
def admin_index():
    return 'Admin module'

@admin.route('/settings')
def settings():
    return 'Admin Settings'


# USER
user = Blueprint('user', __name__, url_prefix='/user')

@user.route('/')
def user_index():
    return 'User module'

@user.route('/profile')
def profile():
    return 'User Profile'


app = Flask(__name__)
app.register_blueprint(admin)
app.register_blueprint(user)

@app.route('/')
def index():
    return render_template('index.html', blueprints=app.blueprints)

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True, port=7000)
Jinja2模板。请记住将此文件放置在根项目的templates文件夹中,默认情况下,flask将在该文件夹中搜索模板

<ul>
  {% for bp_name, bp in blueprints.iteritems() %}
    <li><a href="{{ bp.url_prefix }}">{{ bp.name }}</a></li>
  {% endfor %}
</ul>
管理员

from .custom import MyBlueprint

admin = MyBlueprint('admin', __name__, url_prefix='/admin')
admin.set_data({'color': '#a569bd', 'enabled': true})

# all the blueprint's routes
...
app.py

from admin import admin

app = Flask(__name__)
app.register_blueprint(admin)

@app.route('/')
def index():
    for a, b in app.blueprints:
        print b.bp_data['color']
        print b.bp_data['enabled']
    ...

当然,我的自定义Blueprint类需要做更多的工作,比如验证传递的数据类型,或者在没有必需的值时抛出错误,比如title、require_auth等。从这一点上讲,您必须定义蓝图必须提供给主应用程序才能正常工作的最低数据要求。

这里我向您展示了一个我通常使用的可扩展应用程序模式。事实证明,它工作得很好

目录结构:

YourApp
|- plugins (will contain all the user's plugins)
     |- __init__.py (empty)
     |-plugin1
          |- __init__.py (empty)
          |- loader.py
|- app.py
app.py

from flask import Flask
import os

def plugin_loader(app):
  """ Function for discover new potencial plugins.
  After checking the validity (it means, check if it implements
  'register_as_plugin', load the user defined blueprint"""

  plugins = [x for x in os.listdir('./plugins')
             if os.path.isdir('./plugins/' + x)]
  for plugin in plugins:
    # TODO: Add checking for validation
    module = __import__('plugins.' + str(plugin) + '.loader', fromlist=['register_as_plugin'])

    app = module.register_as_plugin(app)

  return app

# Creates the flask app
app = Flask(__name__)
# Load the plugins as blueprints
app = plugin_loader(app)

print(app.url_map)


@app.route('/')
def root():
  return "Web root!"

app.run()
from flask import Blueprint


plugin1 = Blueprint('plugin1', __name__)

@plugin1.route('/version')
def version():
  return "Plugin 1"

def register_as_plugin(app):
  app.register_blueprint(plugin1, url_prefix='/plugin1')

  return app
plugins/plugin1/loader.py

from flask import Flask
import os

def plugin_loader(app):
  """ Function for discover new potencial plugins.
  After checking the validity (it means, check if it implements
  'register_as_plugin', load the user defined blueprint"""

  plugins = [x for x in os.listdir('./plugins')
             if os.path.isdir('./plugins/' + x)]
  for plugin in plugins:
    # TODO: Add checking for validation
    module = __import__('plugins.' + str(plugin) + '.loader', fromlist=['register_as_plugin'])

    app = module.register_as_plugin(app)

  return app

# Creates the flask app
app = Flask(__name__)
# Load the plugins as blueprints
app = plugin_loader(app)

print(app.url_map)


@app.route('/')
def root():
  return "Web root!"

app.run()
from flask import Blueprint


plugin1 = Blueprint('plugin1', __name__)

@plugin1.route('/version')
def version():
  return "Plugin 1"

def register_as_plugin(app):
  app.register_blueprint(plugin1, url_prefix='/plugin1')

  return app
因此,未来插件应该在loader.py文件中的plugins/目录中实现register_as_plugin函数

有关目录发现的更多信息,请阅读。 有关模块动态导入的更多信息,请阅读


已通过Python 2.7.6、Flask 0.10.1和Unix平台验证。

感谢您的回答。这是真的,但这发生在蓝图中,由编写蓝图并将其添加到我的基础应用程序的人定义。但我现在如何收集所有blueprint主路由和名称,以便在应用程序上下文中生成导航(例如,将其保存在应用程序上下文中,以便稍后调用URL时使用)?此外,如果我想让蓝图作者能够以标准化的方式传递更多的数据(例如,以何种颜色显示指向其作品的链接,或其他什么…),该怎么办?在主应用程序实例中,您有蓝图字典,您可以循环以获取蓝图的每个实例并访问其属性。我会更新我的答案。谢谢,这解决了我的核心问题。尽管如此,我还是希望将更多的设置/数据从蓝图传递到应用程序上下文。。。进一步定制。假设一个蓝图想要告诉它的优先级(它的链接应该放在哪个位置),或者颜色,或者是否禁止它被列出…@j34,我更新了我的aswer关于如何在应用程序和蓝图之间传递更多数据。请检查并让我知道解决方案是否适合您。记住,如果答案对您有效,请将其标记为正确。哇,我一直在考虑flask必须提供一些功能来进行自定义蓝图初始化,而我没有想到继承。。。非常感谢你的努力。