Flask官方文档中的留言板项目解说之__init__.py说明(2)

说明

  • 建立这个init.py文件有两点原因
    ◇: 它包含一个应用工厂函数,create_app(), 加载数据库配置,路由策略设置等,返回一个拥有这些属性的Flask实例。
    ◇: 它是一个包,当项目启动时会自动运行文件中的代码。

  • app = Flask(name, instance_relative_config=True)
    ◇: name是模块名,实例需要知道这个应用的位置在哪,set FLASK_APP=flaskr中的flaskr就是这个name
    ◇: instance_relative_config=True,表明配置文件跟这个实例目录是有关系的

  • app.config.from_mapping(), 为Flask实例关联数据库文件位置,以及保证数据安全
    ◇: SECRET_KEY用于保证数据安全
    ◇: DATABASE,SQLite的数据库文件保存的位置,即项目目录下的instance/flaskr.sqlite

  • app.config.from_pyfile() 如果config.py文件存在,则采用此配置文件。后期项目增加,如需要用到redis、elasticsearch、图片和文档上传路径时, 就需要讲这些配置信息与数据库配置,一并写入到config.py中,方便管理。

  • db.init_app(app),分离扩展的实例化和初始化操作。

源代码如下

  • register_blueprint(auth.bp) 将蓝图注册到Flask实例中。auth文件中有一条: bp=Blueprint('auth', name, url_prefix='/auth'), 蓝图组织视图极其代码的一种方式,提供模块化管理程序路由的功能。
    ◇: 创建一个名为auth的Blueprint
    ◇: name表明这个Blueprint在哪里定义它
    ◇: url_prefix='/auth' 表明所有使用bp.route()的URL前面都加一个auth

  • app.add_url_rule("/", endpoint='index') 主页的默认页面为index.html

源代码如下:

import os

from flask import Flask


def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_mapping(
        SECRET_KEY="dev",
        DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite')
    )

    if test_config is None:
        # Load the instance config, if it exists, when not testing
        app.config.from_pyfile("config.py", silent=True)
    else:
        # Load the test config if passed in
        app.config.from_mapping(test_config)

    # ensure the instance folder exists
    try:
        os.mkdir(app.instance_path)
    except OSError:
        pass

    from . import db
    db.init_app(app)

    from . import auth
    app.register_blueprint(auth.bp)

    from . import blog
    app.register_blueprint(blog.bp)
    app.add_url_rule("/", endpoint='index')

    return app

总结

create_app()是一个工厂函数,是指创建其他对象的对象,本例是创建Flask程序实例,并返回实例APP。只不过在返回前为这个程序实例加载了一些配置,如数据库相关配置、注册了蓝图。最后,APP是具有这些属性的程序实例。

工厂函数的好处有一下几点:

  • 方便测试与部署, 不用将加载的配置写死在某处,可在不同的地方按需配置创建程序实例。
  • 创建扩展对象的操作可以分离到单独的模块,这样可以有效减少循环依赖的发生。
  • 分离扩展的初始化操作。

工厂函数一般在程序包的构造文件中创建,如果你愿意,也可以在程序包内新建的模块来存放,比如factory.py或是app.py。

关于分离扩展的实例化, 这样做的原因是,为了完成扩展的初始化操作,需要实例化扩展类时倒入程序实例。但是使用工厂函数时,并没有一个创建好的程序实例(只有return app, app没有run起来)。如果将初始化操作放在工厂函数中,就没有一个全局的扩展对象可以使用(作用域在create_app中), 比如表示数据库操作的db对象。

为了解决这个问题,就采用init_app()函数来分离扩展的实例化和初始化操作。此项目中关于DB的初始化(建表操作)就放在了db.py文件中。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。