Flask蓝图提供了模块化管理程序路由的功能,使程序结构清晰、简单易懂。为什么要用到蓝图呢?举个例子,一般项目有用户和管理员后台2部分。2个部分要互不影响,又要共享应用配置。这时候蓝图可以“分类模块化”,实现目标要求。
Flask中的蓝图适用于以下情况:
- 将应用程序纳入一组蓝图中。这是大型应用的理想选择; 项目可以实例化一个应用程序对象,初始化几个扩展,并注册一组蓝图。
- 在URL前缀和/或子域中的应用程序上注册蓝图。URL前缀/子域中的参数成为蓝图中所有视图函数的公共视图参数(具有默认值)。
- 在具有不同URL规则的应用程序上多次注册蓝图。
- 通过蓝图提供模板过滤器,静态文件,模板和其他实用程序。蓝图不必实现应用程序或查看功能。
- 在初始化Flask扩展时,在应用程序中为任何这些情况注册蓝图。
Flask中的蓝图不是一个可插拔的应用程序,因为它实际上不是一个应用程序 - 它是一组可以在应用程序上注册的操作,甚至多次。为什么没有多个应用程序对象?您可以这样做(请参阅应用程序调度),但您的应用程序将具有单独的配置,并将在WSGI层进行管理。
相反,蓝图在Flask级别提供分离,共享应用程序配置,并且可以根据需要在注册时更改应用程序对象。缺点是,一旦创建应用程序,您无法取消注册蓝图,而不必销毁整个应用程序对象。
在上一篇的基础上,改造项目
创建admin模块
1、目录结构
在app目录下,新建admin目录
2、蓝图的创建于注册
在admin目录下创建空的__init__.py,表明admin表示它是一个Python的包。
创建蓝图,新建views.py:
from flask import Blueprint
admin_blueprint = Blueprint('admin', __name__)
@admin_blueprint.route('/index')
def admin_index():
return '<h1>this is admin blueprint</h1>'
这里创建了蓝图对象”admin_blueprint”,它使用起来类似于Flask应用的app对象,举个例子,它有自己路由”admin_blueprint.route()”。
初始化Blueprint对象的第一个参数’admin’指定了这个蓝图的名称,第二个参数指定了该蓝图所在的模块名,这里自然是当前文件。
接着在Flask应用主程序中(即app)注册该蓝图,
修改app目录下的__init__.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask
app = Flask(__name__)
from app.controller import test
from flask_sqlalchemy import SQLAlchemy
# 配置数据库的连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@localhost:3306/flask'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
from app.controller import sql
##########本次修改 ############
from .admin.views import admin_blueprint
app.register_blueprint(admin_blueprint, url_prefix='/admin')
测试:
3、蓝图资源
蓝图有自己的目录,它的所有资源都在其目录下。蓝图的资源目录是由创建Blueprint对象时传入的模块名”__name__”所在的位置决定的。同时,我们可以指定蓝图自己的模板目录和静态目录。比如我们创建蓝图时传入:
admin_blueprint = Blueprint('admin', __name__,
template_folder='templates',
static_folder='static')
这样,该蓝图的模板目录就在”admin/templates”下,而静态目录就在”admin/static”下。其实默认值也是这两个位置,不指定也没关系。
我们可以用蓝图对象的”root_path”属性获取其主资源路径,”open_resource()”方法访问主资源路径下的某个文件,比如:
print admin_blueprint.root_path
# Read file ~/admin/doc/info.txt
with admin_blueprint.open_resource('doc/info.txt') as f:
info = f.read()
print info
到这里蓝图的基本用法,就讲完了。
总结:蓝本的作用是使程序结构明晰,模块化