Flask07:蓝图

Blueprint 是一种组织一组相关视图及其他代码的方式。与把视图及其他 代码直接注册到应用的方式不同,蓝图方式是把它们注册到蓝图,然后在工厂函数中 把蓝图注册到应用。

蓝图的基本概念是:在蓝图被注册到应用之后,所要执行的操作的集合。当分配请求 时, Flask 会把蓝图和视图函数关联起来,并生成两个端点之前的 URL 。

Flask 中蓝图有以下用途:

  • 把一个应用分解为一套蓝图。这是针对大型应用的理想方案:一个项目可以实例化 一个应用,初始化多个扩展,并注册许多蓝图。
  • 在一个应用的 URL 前缀和(或)子域上注册一个蓝图。 URL 前缀和(或)子域的 参数成为蓝图中所有视图的通用视图参数(缺省情况下)。
  • 使用不同的 URL 规则在应用中多次注册蓝图。
  • 通过蓝图提供模板过滤器、静态文件、模板和其他工具。蓝图不必执行应用或视图 函数。
  • 当初始化一个 Flask 扩展时,为以上任意一种用途注册一个蓝图。

使用蓝图,那么应用会在 Flask 层中进行管理,共享配置,通过注册按需改 变应用对象。蓝图的缺点是一旦应用被创建后,只有销毁整个应用对象才能注销蓝图。

首先我们看下官方文档的示例:

from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound

simple_page = Blueprint('simple_page', __name__,
                        template_folder='templates')


@simple_page.route('/', defaults={
     'page': 'index'})
@simple_page.route('/')
def show(page):
    try:
        return render_template('pages/%s.html' % page)
    except TemplateNotFound:
        abort(404)

使用很简单和我men前面使用route的方式差不多,再来看下定义:
Flask07:蓝图_第1张图片
通过上面的代码我们也就可以知道蓝图同样可以指定自己的静态资源和模板路径。

那么我们来捋一捋蓝图使用的流程:

  • 定义蓝图,同时可以指定静态资源,模板路径,路由前缀(蓝图下的所有url都有一个url前缀)等等。
  • 注册蓝图

导入蓝图

from blueprint_exmaples import simple_page

注册蓝图

app.register_blueprint(simple_page)

来看看注册蓝图都干了些什么:

  def register_blueprint(self, blueprint, **options):
        first_registration = False

        if blueprint.name in self.blueprints:
            assert self.blueprints[blueprint.name] is blueprint, (
                "A name collision occurred between blueprints %r and %r. Both"
                ' share the same name "%s". Blueprints that are created on the'
                " fly need unique names."
                % (blueprint, self.blueprints[blueprint.name], blueprint.name)
            )
        else:
            self.blueprints[blueprint.name] = blueprint
            self._blueprint_order.append(blueprint)
            first_registration = True

        blueprint.register(self, options, first_registration)

最终是调用 blueprint.register方法进行注册,我们可以跟进去看看,这个方法在blueprint文件中:

    def register(self, app, options, first_registration=False):
        self._got_registered_once = True
        state = self.make_setup_state(app, options, first_registration)

        if self.has_static_folder:
            state.add_url_rule(
                self.static_url_path + "/",
                view_func=self.send_static_file,
                endpoint="static",
            )

        for deferred in self.deferred_functions:
            deferred(state)

        cli_resolved_group = options.get("cli_group", self.cli_group)

        if not self.cli.commands:
            return

        if cli_resolved_group is None:
            app.cli.commands.update(self.cli.commands)
        elif cli_resolved_group is _sentinel:
            self.cli.name = self.name
            app.cli.add_command(self.cli)
        else:
            self.cli.name = cli_resolved_group
            app.cli.add_command(self.cli)

蓝图的第三个参数是 static_folder 。这个参数用以指定蓝图的静态文件所在的 文件夹,它可以是一个绝对路径也可以是相对路径。:

simple_page = Blueprint('simple_page', __name__,
                        static_folder='admin/static',
                        template_folder='templates')

我们可以通过源码看下经过注册后的蓝图的endpoint:

Flask07:蓝图_第2张图片

也就是说通过蓝图注册的路由其实端点就是蓝图名称+点+endpoint,对应静态资源的端点就是:simple_page.static

此时如果使用url_for或者使用静态资源时可以这样引入:

url_for('simple_page.static', filename='style.css')

对于模板文件如果目中的templates文件夹中有相应的模板文件则使用该文件夹下资源,如果没有那么会查找蓝图指定的模板文件夹目录。

优先查找app工程目录下的静态文件夹以及模板文件夹在不指定蓝图对应文件夹路径时。

你可能感兴趣的:(Flask,Python)