蓝图,转载自其他网站,排版未优化

	<div class="copyright-area">原文出处: <a target="_blank" href="http://fanchunke.me/Flask/Flask%E4%B8%AD%E7%9A%84%E8%93%9D%E5%9B%BE%E7%AE%A1%E7%90%86/">Learn Python</a>&nbsp;&nbsp;&nbsp;</div><p>在<a href="http://python.jobbole.com/88591/">Flask中模块化应用的实现</a>一文中,我们曾分析过Flask 0.2版本中的<strong>Module</strong>类。
	这个类能够实现Flask应用的多模块化管理。在0.7版本中,Flask重新设计了模块化管理的内容,提出了“蓝图”的概念,用来取代Module的功能。</p>

什么是“蓝图”

官方文档中对“蓝图”的概念是这样描述的:

Flask uses a concept of blueprints for making application components and supporting common patterns within an application or across applications. Blueprints can greatly simplify how large applications work and provide a central means for Flask extensions to register operations on applications. A Blueprint object works similarly to a Flask application object, but it is not actually an application. Rather it is a blueprint of how to construct or extend an application.

按照以上的描述,可以看出“蓝图”系统在Flask应用的组件化和扩展提供了很大的便利。“组件化”是指可以在Flask层上将一个Flask应用进行“分割”,实现模块化管理,这极大地简化了构建大型应用的流程,也使得应用的维护变得更加容易。另外,“蓝图”还提供了一种Flask扩展在应用上注册操作的核心方法。

“蓝图”和一个Flask应用对象很相似,但是并不是一个Flask应用对象。它是可以注册到Flask应用上的一系列操作(对于此的理解,后文会详细讲到)。使用“蓝图”,可以实现以下的一些功能:

  • 将Flask应用“分割”为一系列“蓝图”的集合,简化了大型应用工作的方式;
  • 在Flask应用上,以 URL 前缀和或子域名注册一个蓝图。可以以不同的URL多次注册一个蓝图;
  • 通过蓝图提供模板过滤器、静态文件、模板和其它功能。

创建“蓝图”对象时发生了什么

“蓝图”和Flask应用的工作方式非常相似。Flask中的“蓝图”系统能够实现很多“蓝图”对象在应用层上的管理,这些“蓝图”对象可以共享应用配置。这意味着“蓝图”应该和Flask应用有一样的运行逻辑,这样一旦蓝图注册到应用上,就可以完全像Flask应用一样工作。

在Flask应用中有一些属性,它们以字典的形式用来存放很多装饰器运行的结果。例如:view_functions这个字典通常存放route装饰器装饰的视图函数,可以用来进行URL匹配;before_request_functions字典会存放before_request装饰器装饰的视图函数,当正式处理请求前会先运行这个字典中的函数••••••为了实现和Flask应用相同的请求处理逻辑,“蓝图”对象也设计了同样的装饰器函数,这些函数都是一些“匿名函数”,只要传递一个参数,就可以将本蓝图上的一些操作映射到Flask应用上去。

例如:before_request装饰器

	<div id="crayon-5ba4e3476d5dc282730265" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="纯文本显示代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切换自动换行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="点击展开代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="复制代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">def before_request(self, f):
"""Like :meth:`Flask.before_request` but for a blueprint.  This function
is only executed before each request that is handled by a function of
that blueprint.
"""
self.record_once(lambda s: s.app.before_request_funcs
    .setdefault(self.name, []).append(f))
return f</textarea></div>
		<div class="crayon-main" style="position: relative; z-index: 1;">
			<table class="crayon-table">
				<tbody><tr class="crayon-row">
			<td class="crayon-nums " data-settings="show">
				<div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;"><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-1">1</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-2">2</div><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-3">3</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-4">4</div><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-5">5</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-6">6</div><div class="crayon-num" data-line="crayon-5ba4e3476d5dc282730265-7">7</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5dc282730265-8">8</div></div>
			</td>
					<td class="crayon-code"><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-1"><span class="crayon-r">def</span><span class="crayon-h"> </span><span class="crayon-e">before_request</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">f</span><span class="crayon-sy">)</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-2"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">"""Like :meth:`Flask.before_request` but for a blueprint.&nbsp;&nbsp;This function</span></div><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-3"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;is only executed before each request that is handled by a function of</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-4"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;that blueprint.</span></div><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-5"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;"""</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-6"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-e">record_once</span><span class="crayon-sy">(</span><span class="crayon-r">lambda</span><span class="crayon-h"> </span><span class="crayon-v">s</span><span class="crayon-o">:</span><span class="crayon-h"> </span><span class="crayon-v">s</span><span class="crayon-sy">.</span><span class="crayon-v">app</span><span class="crayon-sy">.</span><span class="crayon-v">before_request</span><span class="crayon-sy">_</span>funcs</div><div class="crayon-line" id="crayon-5ba4e3476d5dc282730265-7"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-sy">.</span><span class="crayon-e">setdefault</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-sy">[</span><span class="crayon-sy">]</span><span class="crayon-sy">)</span><span class="crayon-sy">.</span><span class="crayon-e">append</span><span class="crayon-sy">(</span><span class="crayon-v">f</span><span class="crayon-sy">)</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5dc282730265-8"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">return</span><span class="crayon-h"> </span><span class="crayon-v">f</span></div></div></td>
				</tr>
			</tbody></table>
		</div>
	</div>

上面的代码中,只要给这个装饰器传递参数s,那么这个装饰器就会将装饰的函数添加到Flask应用的before_request_functions字典当中,并且和该“蓝图”的名字对应起来。这样就可以实现该函数在Flask应用中可用。

由于“蓝图”的创建过程和Flask应用的创建过程是分离的,所以在“蓝图”中使用装饰器不会立即对应用产生效果。“蓝图”中装饰器函数的返回值会经过record_once方法存储在“蓝图”对象的deferred_functions列表中,这为“蓝图”对象的注册提供了一个接口:只要在注册“蓝图”时执行deferred_functions列表中的函数即可。

以下是一个简单的例子:

	<div id="crayon-5ba4e3476d5e5712970581" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="纯文本显示代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切换自动换行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="点击展开代码" style="display: none;"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="复制代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;"># blueprint

>>> from flask import Blueprint
>>> blog = Blueprint(‘blog’, name,
static_folder=‘static’,
template_folder=‘templates’)
>>> @blog.route(’/’)
def index():
return “This is blog home page.”
>>> @blog.before_request
def before_request():
return “This is before_request function.”
>>> @blog.after_request
def after_request():
return “This is after_request function.”
>>> @blog.after_app_request
def after_app_request():
return “This is after_app_request function.”








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# blueprint
>>> from flask import Blueprint
>>> blog = Blueprint ( ‘blog’ , name ,
                     static_folder = ‘static’ ,
                     template_folder = ‘templates’ )
>>> @ blog . route ( ’/’ )
     def index ( ) :
         return “This is blog home page.”
>>> @ blog . before_request
     def before_request ( ) :
         return “This is before_request function.”
>>> @ blog . after_request
     def after_request ( ) :
         return “This is after_request function.”
>>> @ blog . after_app_request
     def after_app_request ( ) :
         return “This is after_app_request function.”


上面的例子中:

  • 首先我们创建了一个“蓝图”对象blog。创建“蓝图”对象时,必须至少传递前两个参数:nameimport_name。也可以传递static_foldertemplate_folderurl_prefix等参数,url_prefix参数也可以在注册蓝图时传入。
  • 之后,我们为blog增加了四条视图函数,每个函数由蓝图的装饰器装饰。此时,我们看一下“蓝图”对象的deferred_functions中有什么:
    	<div id="crayon-5ba4e3476d5ea038979096" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
    	
    		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
    		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="纯文本显示代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切换自动换行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="点击展开代码" style="display: none;"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="复制代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
    		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
    		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">&gt;&gt;&gt; blog.deferred_functions
    

[<function flask.blueprints.<lambda>>,
<function flask.blueprints.<lambda>>,
<function flask.blueprints.<lambda>>,
<function flask.blueprints.<lambda>>
]








1
2
3
4
5
6

>>> blog . deferred _functions
[ < function flask . blueprints . < lambda >> ,
< function flask . blueprints . < lambda >> ,
< function flask . blueprints . < lambda >> ,
< function flask . blueprints . < lambda >>
]


可以看出,此时“蓝图”对象的deferred_functions中已经包含了四个匿名函数,分别对应上面例子中的四个视图函数。一旦“蓝图”被注册到应用上,会执行这四个函数。

注册“蓝图”

Flask应用和“蓝图”中都有注册“蓝图”的接口。

Flask应用 中的接口是:

	<div id="crayon-5ba4e3476d5ee127410963" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="纯文本显示代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切换自动换行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="点击展开代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="复制代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">def register_blueprint(self, blueprint, **options):
"""Registers a blueprint on the application.
.. versionadded:: 0.7
"""
first_registration = False
if blueprint.name in self.blueprints:
    assert self.blueprints[blueprint.name] is blueprint, \
        'A blueprint\'s name collision ocurred between %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
    first_registration = True
blueprint.register(self, options, first_registration)</textarea></div>
		<div class="crayon-main" style="position: relative; z-index: 1;">
			<table class="crayon-table">
				<tbody><tr class="crayon-row">
			<td class="crayon-nums " data-settings="show">
				<div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;"><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-1">1</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-2">2</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-3">3</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-4">4</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-5">5</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-6">6</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-7">7</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-8">8</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-9">9</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-10">10</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-11">11</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-12">12</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-13">13</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5ee127410963-14">14</div><div class="crayon-num" data-line="crayon-5ba4e3476d5ee127410963-15">15</div></div>
			</td>
					<td class="crayon-code"><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-1"><span class="crayon-r">def</span><span class="crayon-h"> </span><span class="crayon-e">register_blueprint</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-o">*</span><span class="crayon-o">*</span><span class="crayon-v">options</span><span class="crayon-sy">)</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-2"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">"""Registers a blueprint on the application.</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-3"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;.. versionadded:: 0.7</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-4"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;"""</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-5"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">first_registration</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">False</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-6"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">if</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-e">name </span><span class="crayon-st">in</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-7"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">assert</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-sy">[</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">]</span><span class="crayon-h"> </span><span class="crayon-st">is</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-8"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">'A blueprint\'s name collision ocurred between %r and '</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-9"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">'%r.&nbsp;&nbsp;Both share the same name "%s".&nbsp;&nbsp;Blueprints that '</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-10"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">'are created on the fly need unique names.'</span><span class="crayon-h"> </span><span class="crayon-o">%</span><span class="crayon-h"> </span><span class="crayon-sy">\</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-11"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-sy">(</span><span class="crayon-v">blueprint</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-sy">[</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">]</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-12"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">else</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-13"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">blueprints</span><span class="crayon-sy">[</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-v">name</span><span class="crayon-sy">]</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-e">blueprint</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5ee127410963-14"><span class="crayon-e">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">first_registration</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">True</span></div><div class="crayon-line" id="crayon-5ba4e3476d5ee127410963-15"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">blueprint</span><span class="crayon-sy">.</span><span class="crayon-e">register</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">options</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">first_registration</span><span class="crayon-sy">)</span></div></div></td>
				</tr>
			</tbody></table>
		</div>
	</div>

这个方法首先会对“蓝图”进行检查,如果已经注册,则会出现一条assert语句。否则,就会调用“蓝图”对象的register方法进行注册。

蓝图对象 中的接口是:

	<div id="crayon-5ba4e3476d5f2371270261" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="纯文本显示代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切换自动换行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="点击展开代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="复制代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important; margin-top: -18px; display: none;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">def register(self, app, options, first_registration=False):
"""Called by :meth:`Flask.register_blueprint` to register a blueprint
on the application.  This can be overridden to customize the register
behavior.  Keyword arguments from
:func:`~flask.Flask.register_blueprint` are directly forwarded to this
method in the `options` dictionary.
"""
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 + '/&lt;path:filename&gt;',
                       view_func=self.send_static_file,
                       endpoint='static')
for deferred in self.deferred_functions:
    deferred(state)</textarea></div>
		<div class="crayon-main" style="position: relative; z-index: 1;">
			<table class="crayon-table">
				<tbody><tr class="crayon-row">
			<td class="crayon-nums " data-settings="show">
				<div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;"><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-1">1</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-2">2</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-3">3</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-4">4</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-5">5</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-6">6</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-7">7</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-8">8</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-9">9</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-10">10</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-11">11</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-12">12</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-13">13</div><div class="crayon-num crayon-striped-num" data-line="crayon-5ba4e3476d5f2371270261-14">14</div><div class="crayon-num" data-line="crayon-5ba4e3476d5f2371270261-15">15</div></div>
			</td>
					<td class="crayon-code"><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-1"><span class="crayon-r">def</span><span class="crayon-h"> </span><span class="crayon-e">register</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">app</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">options</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">first_registration</span><span class="crayon-o">=</span><span class="crayon-t">False</span><span class="crayon-sy">)</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-2"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-s">"""Called by :meth:`Flask.register_blueprint` to register a blueprint</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-3"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;on the application.&nbsp;&nbsp;This can be overridden to customize the register</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-4"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;behavior.&nbsp;&nbsp;Keyword arguments from</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-5"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;:func:`~flask.Flask.register_blueprint` are directly forwarded to this</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-6"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;method in the `options` dictionary.</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-7"><span class="crayon-s">&nbsp;&nbsp;&nbsp;&nbsp;"""</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-8"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">_got_registered_once</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-t">True</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-9"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">state</span><span class="crayon-h"> </span><span class="crayon-o">=</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-e">make_setup_state</span><span class="crayon-sy">(</span><span class="crayon-v">app</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">options</span><span class="crayon-sy">,</span><span class="crayon-h"> </span><span class="crayon-v">first_registration</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-10"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">if</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">has_static_folder</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-11"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-v">state</span><span class="crayon-sy">.</span><span class="crayon-e">add_url_rule</span><span class="crayon-sy">(</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">static_url_path</span><span class="crayon-h"> </span><span class="crayon-o">+</span><span class="crayon-h"> </span><span class="crayon-s">'/&lt;path:filename&gt;'</span><span class="crayon-sy">,</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-12"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="crayon-v">view_func</span><span class="crayon-o">=</span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">send_static_file</span><span class="crayon-sy">,</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-13"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="crayon-v">endpoint</span><span class="crayon-o">=</span><span class="crayon-s">'static'</span><span class="crayon-sy">)</span></div><div class="crayon-line crayon-striped-line" id="crayon-5ba4e3476d5f2371270261-14"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-st">for</span><span class="crayon-h"> </span><span class="crayon-e">deferred </span><span class="crayon-st">in</span><span class="crayon-h"> </span><span class="crayon-r">self</span><span class="crayon-sy">.</span><span class="crayon-v">deferred_functions</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-5ba4e3476d5f2371270261-15"><span class="crayon-h">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="crayon-e">deferred</span><span class="crayon-sy">(</span><span class="crayon-v">state</span><span class="crayon-sy">)</span></div></div></td>
				</tr>
			</tbody></table>
		</div>
	</div>

蓝图对象中的register方法首先会生成一个BlueprintSetupState对象,这个对象将当前应用和当前蓝图的相关信息进行关联,还将作为参数传递到蓝图对象deferred_functions列表中的每一个函数。这样,蓝图中的相关操作就会映射到当前应用当中。

还是以上面的例子为例:

	<div id="crayon-5ba4e3476d5f6353833035" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style="margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important; height: auto;">
	
		<div class="crayon-toolbar" data-settings=" show" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><span class="crayon-title"></span>
		<div class="crayon-tools" style="font-size: 13px !important;height: 19.5px !important; line-height: 19.5px !important;"><div class="crayon-button crayon-nums-button crayon-pressed" title="切换是否显示行编号"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-plain-button" title="纯文本显示代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-wrap-button" title="切换自动换行"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-expand-button" title="点击展开代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-copy-button" title="复制代码"><div class="crayon-button-icon"></div></div><div class="crayon-button crayon-popup-button" title="在新窗口中显示代码"><div class="crayon-button-icon"></div></div><span class="crayon-language">Python</span></div></div>
		<div class="crayon-info" style="min-height: 18.2px !important; line-height: 18.2px !important;"></div>
		<div class="crayon-plain-wrap"><textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="tab-size: 4; font-size: 13px !important; line-height: 15px !important; z-index: 0; opacity: 0;">&gt;&gt;&gt; from flask import Flask

>>> app = Flask(name)
>>> app.url_map
Map([<Rule ‘/static/<filename>’ (HEAD, OPTIONS, GET) -> static>])
>>> app.blueprints
{}
>>> app.before_request_funcs
{}
>>> app.after_request_funcs
{}
>>> app.register_blueprint(blog, url_prefix=’/blog’)
>>> app.url_map
Map([<Rule ‘/blog/’ (HEAD, OPTIONS, GET) -> blog.index>,
<Rule ‘/blog/static/<filename>’ (HEAD, OPTIONS, GET) -> blog.static>,
<Rule ‘/static/<filename>’ (HEAD, OPTIONS, GET) -> static>
])
>>> app.blueprints
{‘blog’: <flask.blueprints.Blueprint at 0x896e7f0>}
>>> app.before_request_funcs
{‘blog’: [<function main.before_request>]}
>>> app.after_request_funcs
{None: [<function main.after_app_request>],
‘blog’: [<function main.after_request>]
}








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

>>> from flask import Flask
>>> app = Flask ( name )
>>> app . url_map
Map ( [ < Rule ‘/static/<filename>’ ( HEAD , OPTIONS , GET ) -> static > ] )
>>> app . blueprints
{ }
>>> app . before_request funcs
{ }
>>> app . after_request funcs
{ }
>>> app . register_blueprint ( blog , url_prefix = ’/blog’ )
>>> app . url_map
Map ( [ < Rule ‘/blog/’ ( HEAD , OPTIONS , GET ) -> blog . index > ,
     < Rule ‘/blog/static/<filename>’ ( HEAD , OPTIONS , GET ) -> blog . static > ,
     < Rule ‘/static/<filename>’ ( HEAD , OPTIONS , GET ) -> static >
     ] )
>>> app . blueprints
{ ‘blog’ : < flask . blueprints . Blueprint at 0x896e7f0 > }
>>> app . before_request funcs
{ ‘blog’ : [ < function main . before_request > ] }
>>> app . after_request funcs
{ None : [ < function main . after_app_request > ] ,
‘blog’ : [ < function main . after_request > ]
}


经过上面的例子,可以发现“蓝图”对象注册到Flask应用时,会在Flask应用对应的地方增加“蓝图”对象的相关信息。例如,blog对象中有一个before_request装饰器,注册成功后,在app.before_request_funcs增加了该信息,并且以蓝图名作为键进行区分。blog对象中还有一个route装饰器,它为蓝图增加了一条URL规则,最终会在Flask应用的url_map中出现。由于在创建蓝图时我们增加了static_folder参数,所以在url_map中我们还可以看到‘/blog/static/<filename>’这样的URL规则。

<div class="post-adds">
    <span data-post-id="88587" class=" btn-bluet-bigger href-style vote-post-up   register-user-only "><i class="fa  fa-thumbs-o-up"></i> <h10 id="88587votetotal">1</h10> 赞</span>
    <span data-book-type="1" data-site-id="13" data-item-id="88587" data-item-type="1" class=" btn-bluet-bigger href-style bookmark-btn  register-user-only "><i class="fa fa-bookmark-o  "></i> 1 收藏</span>

                <a href="#article-comment"><span class="btn-bluet-bigger href-style hide-on-480"><i class="fa fa-comments-o"></i>  评论</span></a>
    
    
    
    <!-- JiaThis Button BEGIN -->
    <div class="jiathis_style_24x24" style="display: inline-flex; position: relative; margin: 0; clear: both;float: right;">
        <a class="jiathis_button_tsina"></a>
        <a class="jiathis_button_weixin"></a>
        <a class="jiathis_button_qzone"></a>
        <a class="jiathis_button_fb hide-on-480"></a>
        <a href="http://www.jiathis.com/share?uid=1745061" class="jiathis jiathis_txt jiathis_separator jtico jtico_jiathis" target="_blank"></a>
    </div>

</div>




    <!-- BEGIN #author-bio -->
</div>
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、资源1项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值