在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']其实不就是设置了一个变量嘛……
你有两种方式来设置配置:
- 直接写出配置的值,像上面那样。
- 对于不适合写在程序里的配置,比如密码等,需要把配置写入系统环境变量,然后使用os模块提供的方法获取:
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.environ.get('MAIL_USERNAME')
如果你使用虚拟环境,设置环境变量时注意要激活虚拟环境,同时不要给变量值加引号。
set MAIL_USERNAME=me@greyli.com # 结果是'me@greyli.com'
set MAIL_USERNAME='me@greyli.com' # 结果是"'me@greyli.com'"
你有三种方式来处理配置。
直接写入主脚本
当你的程序很小的时候,可以直接把配置写在主脚本里:
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)
...
创建不同的配置类
大型项目需要多个配置组合,比如开发时的配置,测试的配置,部署的配置……这样我们需要在配置文件里创建不同的配置类,然后在创建程序实例时引入相应的配置类。
最佳实践是创建一个存储通用配置的基类,然后为不同的使用使用场景创建新的继承基类的配置类:
config.py(这里为开发和测试创建了不同的数据库)
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config: # 基类
SECRET_KEY = 'some secret words'
ITEMS_PER_PAGE = 10
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
'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的内置配置值:http://flask.pocoo.org/docs/0.11/config/#builtin-configuration-values
- Flask配置文档:http://flask.pocoo.org/docs/0.11/config/#configuration-handling
- 《Flask Web开发》中的配置文件:https://github.com/greyli/flasky/blob/master/config.py
– – – – –
更多关于Flask和Web开发的优质原创内容,欢迎关注Hello, Flask! – 知乎专栏。
1.0版本使用单独的配置文件没反应
不太好判断是什么原因。请在 HelloFlask 论坛创建帖子详细说明问题,并给出相关代码。