11. Flask中蓝图
一、蓝图介绍
1. 定义
随着业务代码的增加,将所有代码都放在单个程序文件中,是非常不合适的。这不仅会让代码阅读变得困难,而且会给后期维护带来麻烦。django中的app的主要作用就是将django的项目分成一个个单独的app,然后将所有的app分配不同的处理功能,通过路由分配将它们连接成一个大的django项目,其实Flask中的蓝图和django中的app功能大同小异,下面我们大概的了解一下Flask的蓝图。
一个蓝图定义了可用于单个应用的视图、模板、静态文件等等的集合。可以把蓝图当做你的应用的管理面板。
2. 运行机制
蓝图是保存了一组将来可以在应用对象上执行的操作。注册路由就是一种操作,当在程序实例上调用route装饰器注册路由时,这个操作将修改对象的url_map路由映射列表。当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一个项。当执行应用对象的 register_blueprint() 方法时,应用对象从蓝图对象的 defered_functions 列表中取出每一项,即调用应用对象的 add_url_rule() 方法,这将会修改程序实例的路由映射列表。
二、蓝图使用
比较好的习惯是将蓝图放在一个单独的包里,所以让我们先创建一个”admin”包,并创建一个空的__init__.py
表示它是一个Python的包。现在我们来编写蓝图,将其存在”admin/admin_module.py”文件里。
from flask import Blueprint
admin_bp = Blueprint('admin', __name__)
@admin_bp.route('/')
def index(name):
return '<h1>Hello, this is admin blueprint</h1>'
我们创建了蓝图对象”admin_bp”,它使用起来类似于Flask应用的app对象,比如,它可以有自己的路由admin_bp.route()
。初始化Blueprint对象的第一个参数admin
指定了这个蓝图的名称,第二个参数指定了该蓝图所在的模块名,这里自然是当前文件。
接下来,我们在应用中注册该蓝图。在Flask应用主程序中,使用app.register_blueprint()
方法即可:
from flask import Flask
from admin.admin_module import admin_bp
app = Flask(__name__)
app.register_blueprint(admin_bp, url_prefix='/admin')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
app.register_blueprint()
方法的url_prefix
指定了这个蓝图的URL前缀。现在,访问http://localhost:5000/admin/
就可以加载蓝图的index视图了。你也可以在创建蓝图对象时指定其URL前缀:
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
# 这样注册时就无需指定
app.register_blueprint(admin_bp)
三、蓝图资源
蓝图有自己的目录,它的所有资源都在其目录下。蓝图的资源目录是由创建Blueprint对象时传入的模块名__name__
所在的位置决定的。同时,我们可以指定蓝图自己的模板目录和静态目录。比如我们创建蓝图时传入:
admin_bp = Blueprint('admin', __name__,
template_folder='templates',
static_folder='static')
这样,该蓝图的模板目录就在”admin/templates”下,而静态目录就在”admin/static”下。当然,其实默认值就是这两个位置,不指定也没关系。我们可以用蓝图对象的root_path
属性获取其主资源路径,open_resource()
方法访问主资源路径下的某个文件,比如:
# Assume current app is at /home/bjhee/flask-app,
# this will return /home/bjhee/flask-app/admin
print admin_bp.root_path
# Read file /home/bjhee/flask-app/admin/files/info.txt
with admin_bp.open_resource('files/info.txt') as f:
info = f.read()
print info
四、构建URL
我们曾在入门系列-路由中介绍过构建URL的方法url_for()
。其第一个参数我们称为端点(Endpoint),一般指向视图函数名或资源名。蓝图的端点名称都要加上蓝图名为前缀,还记得上例的蓝图名是什么吗?对,”admin“,创建Blueprint对象时的第一个参数。当我们通过端点名称来获取URL时,我们要这样做:
from flask import url_for
url_for('admin.index') # return /admin/
url_for('admin.static', filename='style.css') # return /admin/static/style.css
这样才能获得”admin”蓝图下视图或资源的URL地址。如果,url_for()
函数的调用就在本蓝图下,那蓝图名可以省略,但必须留下.
表示当前蓝图:
url_for('.index')
url_for('.static', filename='style.css')