flask 蓝图

解释1:

允许将应用组织为模块,每个模块有自洽的 MVC,开发者做些工作可以使模块间依赖尽可能少,必要时可以按 blueprint 为单位做垂直拆分。

依赖反转,允许把 route 挂到 blueprint 对象而非全局 app 对象上。

解释2:

1 概述

蓝图/Blueprint是Flask应用程序组件化的方法,可以在一个应用内或跨越 多个项目共用蓝图。使用蓝图可以极大地简化大型应用的开发难度,也为Flask扩展 提供了一种在应用中注册服务的集中式机制。

2 初识蓝图

蓝图/Blueprint对象用起来和一个应用/Flask对象差不多,最大的区别在于一个 蓝图对象没有办法独立运行,必须将它注册到一个应用对象上才能生效。

使用蓝图可以分为三个步骤

1.创建一个蓝图对象

ezbp =Blueprint("ezbp",__name__)

2.在这个蓝图对象上进行操作,入注册路由、指定静态文件夹、注册模板过滤器...

@ezbp.route('/')defezbp_index():return'Welcome to my blueprint'

3.在应用对象上注册这个蓝图对象

app.register_blueprint(ezbp,url_prefix='/ezbp')

当这个应用启动后,通过/ezbp/可以访问到蓝图中定义的视图函数。

考察上面的代码,可以看到在蓝图对象上注册路由的方法和在应用对象上完全 一样,那么,值得思考的是,蓝图和应用对象的运行机制是一样的吗?

example:

#-*- coding:utf-8 -*-fromflaskimportFlask,Blueprintapp= Flask(__name__)

@app.route('/')defapp_index():return'go blueprint'ezbp = Blueprint("ezbp",__name__)

@ezbp.route('/')defezbp_index():return'Welcome to my blueprint'app.register_blueprint(ezbp,url_prefix='/ezbp')

app.run(host='0.0.0.0',port=80)

ouptut:

3 运行机制———说白了就是会自动补充URL前缀,并且能使用相同的视图函数

蓝图并不是一个可插拔的应用 —— 它只是保存了一组将来可以在应用对象上执行 的操作—— 注册路由就是一种操作。

当在应用对象上调用route 装饰器或使用add_url_rule()方法注册路由时, 我们已经知道,这个操作将修改应用对象的两张路由表:url_map和view_functions; 然而,蓝图对象根本就没有路由表,当我们在蓝图对象上调用route装饰器或使用 add_url_rule()方法注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一项:下图为blueprint和FLask route的对比

flask 蓝图_第1张图片

lambad s: s.add_url_rule('/',view_func=ezbp_index)定义了一个匿名函数, 参数s就是将来被传入的应用对象。当执行应用对象的register_blueprint()方法时,应用对象将从蓝图对象的defered_functions列表中取出每一项,并以自身 作为参数执行该匿名函数 —— 即调用应用对象的add_url_rule()方法,这将真正的 修改应用对象的两张路由表。

所以说,蓝图这个名字起得的确恰当,蓝图的那些方法仅仅记录了未来应该发生的操作, 而不是当即实现。

2 蓝图的URL前缀

继续使用前一节的图,注意其中被橘黄色荧光笔涂抹的代码:

当我们在应用对象上注册一个蓝图时,需要指定一个url_prefix关键字 参数(这个参数默认是/)。在上面的图中可以看到,在应用最终的路由表url_map中,在蓝图上注册的路由URL自动被加上了这个前缀。

这相当有用,我们可以在多个蓝图中使用相同的URL规则而不会最终引起冲突,只要在 注册蓝图时将不同的蓝图挂接到不同的自路径即可 —— 想一想对于大型应用而言,不同 的蓝图通常是不同的人员开发的,你很难保证URL规则不发生冲突!

example:

#-*- coding:utf-8 -*-fromflaskimportFlask,Blueprint

shop= Blueprint('shop','shop')

@shop.route('/')defv_index():return'shop root'vip= Blueprint('vip','vip')

@vip.route('/')defv_index():return'vip homepage'admin= Blueprint('admin','admin')

@admin.route('/')defv_index():return'admin root'app= Flask(__name__)

app.register_blueprint(shop,url_prefix='/')

app.register_blueprint(admin,url_prefix='/admin')

app.register_blueprint(vip,url_prefix='/vip')

app.run(host='0.0.0.0',port=80)

output:

4 蓝图的endpoint———加上蓝图前缀

图继续,这次关注绿色荧光笔涂抹的代码:

flask 蓝图_第2张图片

我们创建蓝图对象时,第一个参数指定了蓝图的名字。当在应用中注册蓝图时, 蓝图的路由项中的访问点endpoint被自动添加了这个名字。

这有什么用?这涉及到url_for()的正确工作与否。

当不同的团队开发不同的蓝图时,和URL规则类似,你很难保证他们的视图函数名 彼此不同,尤其像index这样俗套的名字。如果不对来自不同蓝图的endpoint 进行区隔,那么url_for('index')到底应该生成那个URL?这显然无法确定。

一旦给不同蓝图的endpoint加上了蓝图名前缀,我们可以确切地告诉url_for() 了:

url_for('shop.v_index')#/shop/url_for('admin.v_index')#/admin/

example:

#-*- coding:utf-8 -*-fromflaskimportFlask,Blueprint,url_for,render_template_string

shop= Blueprint('shop',__name__)

@shop.route('/')defv_index():return'''

  • Here is shop you can go admin
  • '''admin= Blueprint('admin',__name__)

    @admin.route('/')defv_index():return'''

  • Here is admin you can go shop
  • '''app= Flask(__name__)

    app.register_blueprint(shop,url_prefix='/shop')

    app.register_blueprint(admin,url_prefix='/admin')

    @app.route('/')defv_index():

    tpl='''

    • shop
    • admin
    • '''returnrender_template_string(tpl)

      app.run(host='0.0.0.0',port=80)

      ouput:

      flask 蓝图_第3张图片

      5 注册静态目录路由

      和应用对象不同,蓝图对象创建时不会默认注册静态目录的路由。需要我们在 创建时指定static_folder参数。

      下面的示例将蓝图所在目录下的ezstatic目录设置为静态目录:

      admin = Blueprint("admin",__name__,static_folder='ezstatic')

      app.register_blueprint(admin,url_prefix='/admin')

      默认情况下Flask使用文件夹的名称注册静态文件夹的路由:

      +------------------------------------------------------------------+

      |  url            | endpoint        | view_function              |

      +------------------------------------------------------------------+

      |  /admin/ezstatic | admin.static    | Blueprint.send_static_file |

      +------------------------------------------------------------------+

      现在就可以使用/admin/ezstatic/访问mystatic目录下的静态文件了。

      定制静态目录URL规则 :可以在创建蓝图对象时使用static_url_path来改变静态 目录的路由。下面的示例将为ezstatic文件夹的路由设置为/lib:

      admin = Blueprint("admin",__name__,static_folder='ezstatic',static_url_path='/lib')

      app.register_blueprint(admin,url_prefix='/admin')

      这时的路由表如下:

      +------------------------------------------------------------------+

      |  url            | endpoint        | view_function              |

      +------------------------------------------------------------------+

      |  /admin/lib      | admin.static    | Blueprint.send_static_file |

      +------------------------------------------------------------------+

      这样我们可以使用地址/admin/lib/main.css访问ezstatic目录下的main.css文件了

      你可能感兴趣的:(flask 蓝图)