定义

简单来说,Blueprint 是一个存储视图方法的容器,这些操作在这个Blueprint 被注册到一个app之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。

在其他地方,这个概念可能叫组路由

功能

蓝图的功能:主要是将大型项目分层解耦,模块化

  • 可以将相同模块的视图函数放在同一蓝图下,同一个文件中,方便管理。
  • 应用URL前缀和子域名在一个蓝图上
  • 应用不同的URL规则多次注册一个蓝图
  • 通过蓝图提供模板过滤器、静态文件、模板和其它功能。(一个蓝图不一定要实现应用或者视图函数)
  • 初始化一个Flask扩展时,在这些情况中注册蓝图

基本语法

  1. 导入蓝图
  2. 定义蓝图
  3. 注册蓝图

示例代码:

  1. # blueprints/user.py
  2. from flask import Blueprint
  3. # 1. 初始化蓝图
  4. user_bp = Blueprint('user', __name__)
  5. # 2. 定义蓝图视图
  6. @user_bp.route('/profile/')
  7. def profile():
  8. return "个人中心页面"
  9. @user_bp.route('/settings/')
  10. def settings():
  11. return "个人中心设置页面"
  12. # app.py
  13. app = Flask(__name__)
  14. app.register_blueprint(user_bp) # 注册蓝图

蓝图源代码

  1. class Blueprint(_PackageBoundObject):
  2. """Represents a blueprint. A blueprint is an object that records
  3. functions that will be called with the
  4. :class:`~flask.blueprints.BlueprintSetupState` later to register functions
  5. or other things on the main application. See :ref:`blueprints` for more
  6. information.
  7. .. versionadded:: 0.7
  8. """
  9. warn_on_modifications = False
  10. _got_registered_once = False
  11. def __init__(self, name, import_name, static_folder=None,
  12. static_url_path=None, template_folder=None,
  13. url_prefix=None, subdomain=None, url_defaults=None,
  14. root_path=None):
  15. _PackageBoundObject.__init__(self, import_name, template_folder,
  16. root_path=root_path)
  17. self.name = name
  18. self.url_prefix = url_prefix
  19. self.subdomain = subdomain
  20. self.static_folder = static_folder
  21. self.static_url_path = static_url_path
  22. self.deferred_functions = []
  23. if url_defaults is None:
  24. url_defaults = {}
  25. self.url_values_defaults = url_defaults
  26. # name: 蓝图名字
  27. # import_name: 通常是__name__,指定蓝图资源文件夹
  28. # static_folder: 指向fs中的目录,公开一个静态文件的目录(可以使用绝对路径与相对路径)
  29. # template_folder: 公开蓝图模板目录
  30. # subdomain: 使用蓝图实现子域名

蓝图路由前缀

蓝图可以在路由前挂载,即蓝图路由前缀,如以下url中的user前缀

  1. domain/user/settings/
  2. domain/user/profile/

定义方法如下(注意添加前缀时,前缀的斜杠与蓝图函数的路由斜杠问题):

  1. # blueprints/user.py
  2. from flask import Blueprint
  3. # 1. 初始化蓝图
  4. user_bp = Blueprint('user', __name__, url_prefix="/user") # 添加路由前缀
  5. # 2. 定义蓝图
  6. @user_bp.route('/profile/')
  7. def profile():
  8. return "个人中心页面"

蓝图资源文件

蓝图模板文件的查询顺序:

  1. 如果 templates 目录中有相应的模板文件,就直接使用
  2. 如果 templates 目录中没有相应的模板文件, 就去定义蓝图时指定的路径中寻找。蓝图中指定的路径可以为相对路径(相对的是当前这个蓝图文件所在的目录: blueprint_name/templates

蓝图静态文件的查询顺序

  1. 如果使用url_for('static')指定了 static目录,那么只会在app指定的 static目录查找
  2. 如果模板文件指定蓝图的名字url_for('news.static') ,那么就会到 blueprint_name/static_folder目录下查找

构建URLs

当你想要从一个页面链接到另一个页面,你可以像通常一个样使用 url_for() 函数,只是你要在 URL 的末端加上蓝图的名称和一个点(.)作为前缀:

  1. 使用url_for()函数时,需要在endpoint 前加上所调用蓝图的名字

    1. url_for('admin.index')
  2. 即使在同一个蓝图中反转视图函数,也要指定蓝图的名字

    1. url_for('.index')

蓝图实现子域名

使用蓝图实现子域名

  1. 创建蓝图时,传递subdomain=xxxx
  2. 在主app文件中,需要配置SERVER_NAME

子域名的实现也是使用Blueprint来实现的,首先创建一个cms文件

  1. from flask import Blueprint
  2. cms_bp = Blueprint('cms',__name__,subdomain='cms') # 1. 设置子域名为 cms
  3. @cms_bp.route('/')
  4. def cms_index():
  5. return '我是cms的管理平台'

/private/etc/hosts中修改域名对应

  1. 127.0.0.1 test.com
  2. 127.0.0.1 cms.test.com

在主文件中添加蓝图和设置域名

  1. app.register_blueprint(cms_bp)
  2. app.config['SERVER_NAME'] = 'test.com:5000' # 2. 配置 SERVER_NAME

这样我们就能通过http://cms.test.com:5000/
访问cms.test.com这个字域名下面的视图函数。