之前在Flask介绍里说过,Flask主要的特点之一是大多数功能是由丰富的扩展来完成的。从另一方面来看,Flask之所以广受欢迎,也离不开众多良好扩展的支持。
  下面以Flask-Bootstrap为例,介绍扩展的相关内容。关于项目结构,工厂函数,蓝本等内容后面会介绍,在这里不做深入。
  安装与导入
  安装
  扩展可以使用easy_install或pip安装,使用pip:
  pip install 扩展名
  扩展的命名方式一般为“flask-ability”,这里的ability是扩展要集成的库或是功能,例如flask-script,flask-bootstrap。
  pip install flask-bootstrap
  导入
  导入时扩展中的横线换成下划线,即“flask_ability”。
  from flask_bootstrap import Bootstrap
  配置
  扩展的配置和Flask的配置以及自定义的配置一样,都存储在配置字典里,所以你可以把它写在单独的配置文件里,然后在创建程序实例时加载。具体细节见Flask项目配置。
  初始化
  有两种方法初始化扩展:
  1、实例化扩展类
  在一个小的程序里,可以直接导入扩展类,传入当前的程序实例(即“app”):
  from flask import Flask
  from flask_bootstrap import Bootstrap
  app = Flask(__name__)
  bootstrap = Bootstrap(app)
  2、使用初始化方法
  每个扩展都会提供一个初始化方法: init_app 。扩展在这个方法里加载相应的配置,实现初始化操作。一个典型的例子:
  flask_bootstrap/__init__.py
  class Bootstrap(object):
  def __init__(self, app=None):
  if app is not None:
  self.init_app(app)
  def init_app(self, app):
  app.config.setdefault('BOOTSTRAP_USE_MINIFIED', True)
  app.config.setdefault('BOOTSTRAP_CDN_FORCE_SSL', False)
  ...
  在这里可以看到,如果使用上一种方法,实例化Bootstrap并传入程序实例,同样会调用init_app()方法。
  在使用工厂函数来创建程序时,我们这样初始化扩展:
  from flask import Flask
  from flask_bootstrap import Bootstrap
  from config import config
  bootstrap = Bootstrap()  # 不传入程序实例
  def create_app():
  app = Flask(__name__)
  app.config.from_object(config)
  bootstrap.init_app(app)
  return app
  把这个函数存为单独的文件,然后在你的程序主脚本里使用app = create_app()来创建程序实例。
  管理
  对于小项目,你可以直接把扩展的导入和初始化都放在主脚本里。大的项目有两种常见的管理方式:
  1、和工厂函数(create_app())放在一起
  放在程序包的构造文件(app/__init__.py),或是单独创建的文件(app.py)里。见上面的代码片段。
  2、放在单独的文件里
  当使用的扩展比较多时,你也可以创建一个单独的文件来管理。像你为表单和数据库模型创建的文件一样,你可以把它命名为extensions.py。
  extensions.py
  from flask_bootstrap import Bootstrap
  bootstrap = Bootstrap()  # 不传入程序实例
  然后像上面一样在create_app()里初始化:
  from flask import Flask
  from extensions import bootstrap
  from config import config
  def create_app():
  app = Flask(__name__)
  app.config.from_object(config)
  bootstrap.init_app(app)
  return app
  你可能会对上面的各种名称感到疑惑,比如为什么所有的扩展都有一个init_app方法,为什么扩展的名称(flask-bootstrap),导入的名称(flask_bootstrap),导入的扩展类的名称(Bootstrap)都有相同的命名模式?嗯,答案很简单,因为这是Flask扩展开发文档里的要求……