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')


posted @ 2020-04-11 16:17  qi.hu  阅读(217)  评论(0编辑  收藏  举报