在Flask项目中,我们会用到很多配置(Config)。比如说设置秘钥,设置数据库地址,像下面这样:
app.config['SECRET_KEY'] = 'some strange words'
在很多情况下,你需要设置程序的某些行为,这时你就需要使用配置变量。在Flask中,配置变量就是一些大写形式的Python变量,你也可以称之为配置参数或配置键。
使用统一的配置变量可以避免在程序中以硬编码的形式设置程序。
在一个项目中,你会用到许多配置,Flask提供的配置,扩展(比如flask-sqlalchemy,flask-mail)提供的配置,还有程序特定的配置。
和平时使用的变量不同,这些配置变量都通过Flask对象的app.config属性作为统一的接口来设置和获取,它指向的Config类实际上是字典的的子类,
所以你可以像操作其它字典一样操作它。
为什么需要使用自己的配置?
假设你在做一个博客,有十个视图函数都定义了每页显示的文章数。当你写好以后,发现每页的文章太多,想把这个值改小一点,这时你要找到这十个视图函数,分别修改这个值,很蠢吧?使用配置你就使用一行控制所有的变量:
app.config['POST_PER_PAGE'] = 12
我们可以用以下几种方式来设置配置
1. 直接写出配置的值
比如,
app.config['SECRET_KEY'] = 'some strange words'
app.config['POST_PER_PAGE'] = 12
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', 'me@greyli.com')
我们有三种方式处理配置
1. 直接写入主脚本
当你的程序很小的时候,可以直接把配置写在主脚本里:
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
)
2. 通过Json文件,app.config.from_json
settings.json文件内容如下:
{
"FLASK_ENV":"json"
"SECRET_KEY":"some secret words"
}
在创建程序实例后导入配置:
from flask import Flask
app =Flask(__name__)
import os
basedir = os.path.abspath(os.path.dirname(__file__))
jsondir =os.path.join(basedir,'settings.json')
print('配置前',app.config.get('FLASK_ENV'))
#使用 json文件 配置app环境变量
app.config.from_json(jsondir)
print('配置后',app.config.get('FLASK_ENV'))
#------运行结果----------------
配置前 None
配置后 json
3. 通过 python文件,app.config.from_object 或 app.config.from_pyfile
程序逐渐变大时,配置也逐渐增多,写在主脚本里太占地方,不够优雅(这时你应该已经把表单,路由,数据库模型等等分成独立的文件了。关于大型项目结构,后续会总结)。我们可以创建一个单独的配置文件。
config.py 或 setting.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')
...
4. 创建不同的配置类
大型项目需要多个配置组合,比如开发时的配置,测试的配置,部署的配置……这样我们需要在配置文件里创建不同的配置类,然后在创建程序实例时引入相应的配置类。
最佳实践是创建一个存储通用配置的基类,然后为不同的使用使用场景创建新的继承基类的配置类:
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']) # 获取相应的配置类
...