Flask项目配置(Configuration)

转载:https://zhuanlan.zhihu.com/p/24055329?refer=flask


在Flask项目中,我们会用到很多配置(Config)。比如说设置秘钥,设置数据库地址,像下面这样:

...
app.config['SECRET_KEY'] = 'some strange words'

Flask的配置对象(config)是一个字典的子类(subclass),所以你可以把配置用键值对的方式存储进去。这是一个通用的处理接口,Flask内置的配置,扩展提供的配置,你自己的配置,都集中在一处。

为什么需要使用自己的配置?
假设你在做一个博客,有十个视图函数都定义了每页显示的文章数。当你写好以后,发现每页的文章太多,想把这个值改小一点,这时你要找到这十个视图函数,分别修改这个值,很蠢吧?使用配置你就使用一行控制所有的变量:
app.config['POST_PER_PAGE'] = 12
在十个视图函数里使用配置变量代替固定值:
post_per_page = app.config['POST_PER_PAGE']
其实不就是设置了一个变量嘛……

你有两种方式来设置配置:

  1. 直接写出配置的值,像上面那样。
  2. 对于不适合写在程序里的配置,比如密码等,需要把配置写入系统环境变量,然后使用os模块的getenv()方法获取,第二个参数作为默认值:
set MAIL_USERNAME=me@greyli.com  # windows
export MAIL_USERNAME=me@greyli.com  # *unix

获取变量并写入:

import os

from flask import Flask

app = Flask(__name__)
app.config['MAIL_USERNAME'] = os.getenv('MAIL_USERNAME', '[email protected]')
如果你使用虚拟环境,设置环境变量时注意要激活虚拟环境,同时不要给变量值加引号。
set MAIL_USERNAME=me@greyli.com  # 结果是'[email protected]'
set MAIL_USERNAME='[email protected]'  # 结果是"'[email protected]'"


你有三种方式来处理配置。


直接写入主脚本

当你的程序很小的时候,可以直接把配置写在主脚本里:

from flask import Flask

app = Flask(__name__)
app.config['SECRET_KEY'] = 'some secret words'
app.config['DEBUG'] = True
app.config['ITEMS_PER_PAGE'] = 10

使用字典的update方法可以简化代码:

from flask import Flask

app = Flask(__name__)
app.config.update(
    DEBUG=True,
    SECRET_KEY='some secret words',
    ITEMS_PER_PAGE=10
)


单独的配置文件

程序逐渐变大时,配置也逐渐增多,写在主脚本里太占地方,不够优雅(这时你应该已经把表单,路由,数据库模型等等分成独立的文件了。关于大型项目结构,后续会总结)。我们可以创建一个单独的配置文件。和上面同样的配置,现在可以改写为:

config.py

SECRET_KEY = 'some secret words'
DEBUG = True
ITEMS_PER_PAGE = 10

在创建程序实例后导入配置:

import config

...
app = Flask(__name__)
app.config.from_object(config)
...

或是:

...
app = Flask(__name__)
app.config.from_pyfile('config.py')
...

创建不同的配置类

大型项目需要多个配置组合,比如开发时的配置,测试的配置,部署的配置……这样我们需要在配置文件里创建不同的配置类,然后在创建程序实例时引入相应的配置类。

最佳实践是创建一个存储通用配置的基类,然后为不同的使用使用场景创建新的继承基类的配置类:

config.py(这里为开发和测试创建了不同的数据库)

import os
basedir = os.path.abspath(os.path.dirname(__file__))


class BaseConfig:  # 基本配置类
    SECRET_KEY = os.getenv('SECRET_KEY', 'some secret words')
    ITEMS_PER_PAGE = 10


class DevelopmentConfig(BaseConfig):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = os.getenv('DEV_DATABASE_URL', 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')


class TestingConfig(BaseConfig):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = os.getenv('TEST_DATABASE_URL', 'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')
    WTF_CSRF_ENABLED = False


config = {
    'development': DevelopmentConfig,
    'testing': TestingConfig,

    'default': DevelopmentConfig
}


通过from_object()方法导入配置:


from config import config  # 导入存储配置的字典

...
app = Flask(__name__)
app.config.from_object(config['development'])  # 获取相应的配置类
...


关于大型项目结构,扩展的初始化,使用程序工厂函数创建程序实例等内容见后续。

猜你喜欢

转载自blog.csdn.net/angus_17/article/details/80481449