代码抽取

  • 目标:将特定逻辑代码抽取到指定的类中,各司其职,放便后续项目维护

配置文件

  • 在与 manage.py 同级目录下创建 config.py 文件,用作于项目的配置文件

import redis


class Config(object):
    """工程配置信息"""
    SECRET_KEY = "EjpNVSNQTyGi1VvWECj9TvC/+kq3oujee2kTfQUs8yCM6xX9Yjq52v54g+HVoknA"

    DEBUG = True

    # 数据库的配置信息
    SQLALCHEMY_DATABASE_URI = "mysql://root:mysql@127.0.0.1:3306/information"
    SQLALCHEMY_TRACK_MODIFICATIONS = True

    # redis配置
    REDIS_HOST = "127.0.0.1"
    REDIS_PORT = 6379

    # session 配置
    SESSION_TYPE = "redis"  # 指定 session 保存到 redis 中
    SESSION_USE_SIGNER = True  # 让 cookie 中的 session_id 被加密签名处理
    SESSION_REDIS = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT)  # 使用 redis 的实例
    PERMANENT_SESSION_LIFETIME = 86400  # session 的有效期,单位是秒
  • manager.py 中引入 Config 类,直接使用
from config import Config

app = Flask(__name__)

# 配置
app.config.from_object(Config)

运行测试

业务逻辑独立

在整个项目文件夹中,除了启动文件 manage.py 和配置文件 config.py 放在根目录,其他具体业务逻辑文件都放在一个单独的文件夹内,与 manage.py 同级

  • 创建 info Package,与 manage.py 同级

  • manage.py 只做最基本的启动工作,将 app 的创建操作移动到 info__init__.py 文件中
import redis
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect
from flask_session import Session
from config import Config

app = Flask(__name__)

# 配置
app.config.from_object(Config)
# 配置数据库
db = SQLAlchemy(app)
# 配置redis
redis_store = redis.StrictRedis(host=Config.REDIS_HOST, port=Config.REDIS_PORT)
# 开启csrf保护
CSRFProtect(app)
# 设置session保存位置
Session(app)
  • manage.py 的代码为
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from info import app, db

# Flask-script
manager = Manager(app)
# 数据库迁移
Migrate(app, db)
manager.add_command('db', MigrateCommand)


@app.route('/index')
def index():
    return 'index'


if __name__ == '__main__':
    manager.run()

运行测试

项目多种配置

一个web程序在开发阶段可能与生产阶段所需要的配置信息可能不一样,所以为了实现此功能,可以给不同情况创建不同的配置类,比如开发阶段使用的配置类名为 DevelopementConfig,生产阶段使用的配置类名为 ProdutionConfig

  • 修改 config.py 文件的配置文件如下
import redis


class Config(object):
    """工程配置信息"""

    SECRET_KEY = "EjpNVSNQTyGi1VvWECj9TvC/+kq3oujee2kTfQUs8yCM6xX9Yjq52v54g+HVoknA"

    # 数据库的配置信息
    SQLALCHEMY_DATABASE_URI = "mysql://root:mysql@127.0.0.1:3306/information"
    SQLALCHEMY_TRACK_MODIFICATIONS = False

    # redis配置
    REDIS_HOST = "127.0.0.1"
    REDIS_PORT = 6379

    # flask_session的配置信息
    SESSION_TYPE = "redis"  # 指定 session 保存到 redis 中
    SESSION_USE_SIGNER = True  # 让 cookie 中的 session_id 被加密签名处理
    SESSION_REDIS = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT)  # 使用 redis 的实例
    PERMANENT_SESSION_LIFETIME = 86400  # session 的有效期,单位是秒


class DevelopementConfig(Config):
    """开发模式下的配置"""
    DEBUG = True


class ProductionConfig(Config):
    """生产模式下的配置"""
    pass

接下来思考如何能才更快速的针对不同的布署环境去使用不同的配置

工厂类方法创建应用实例

要在不同环境下去使用不同的配置,那么可以在 manage.py 文件中给 info 包传入不同的配置信息,让 ihome 去根据传入指定配置去创建 app,所以可以在 info__init__.py 文件中添加一个工厂方法,根据传入的配置不同创建其对应的应用实例

  • config.py 文件中添加以下代码
# 定义配置字典
config = {
    "development": DevelopementConfig,
    "production": ProductionConfig
}
  • 修改 info 文件夹下 __init__.py,添加 create_app 的工厂方法
def create_app(config_name):
    """通过传入不同的配置名字,初始化其对应配置的应用实例"""
    pass
  • 修改 manage.py 文件中的代码
from info import create_app, db

# 创建 app,并传入配置模式:development / production
app = create_app('development')
  • __init__.py 文件中创建 app 实例的方法移动到 create_app 方法中
from config import config


# 数据库
db = SQLAlchemy()
redis_store = None


def create_app(config_name):
    """通过传入不同的配置名字,初始化其对应配置的应用实例"""

    app = Flask(__name__)

    # 配置
    app.config.from_object(config[config_name])
    # 配置数据库
    db.init_app(app)
    # 配置redis
    global redis_store
    redis_store = redis.StrictRedis(host=config[config_name].REDIS_HOST, port=config[config_name].REDIS_PORT)
    # 开启csrf保护
    CSRFProtect(app)
    # 设置session保存位置
    Session(app)

    return app