Flask项目配置(Configuration) - 知乎
在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']
其实不就是设置了一个变量嘛……
你有两种方式来设置配置:
set [email protected] # windows
export [email protected] # *unix
获取变量并写入:
import os
from flask import Flask
app = Flask(__name__)
app.config['MAIL_USERNAME'] = os.getenv('MAIL_USERNAME', '[email protected]')
如果你使用虚拟环境,设置环境变量时注意要激活虚拟环境,同时不要给变量值加引号。
set [email protected] # 结果是'[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']) # 获取相应的配置类
...
关于大型项目结构,扩展的初始化,使用程序工厂函数创建程序实例等内容见后续。
- - - - -
更多关于Flask和Web开发的优质原创内容,欢迎关注Hello, Flask! - 知乎专栏。