Flask 配置方法
python from flask import Flask
app = Flask(name) app.config['DEBUG'] = True app.config['SECRET_KEY'] = 'dev-key-please-change' print(app.config['DEBUG']) # True
这种方式适合小型脚本或快速测试,但密钥和数据库地址等敏感信息不应硬编码在代码中。生产环境务必使用更安全的方式。
## 专用配置方法一览
Flask 提供了一组 `from_xxx()` 方法,可以从不同来源加载配置。这是官方推荐且最常用的手段。
### 从类加载配置(推荐用于多环境切换)
将配置定义为 Python 类,属性名必须全大写。然后调用 `app.config.from_object()`:
```python
class Config:
SECRET_KEY = 'base-secret'
DEBUG = False
class DevelopmentConfig(Config):
DEBUG = True
DATABASE_URI = 'sqlite:///dev.db'
app = Flask(__name__)
app.config.from_object(DevelopmentConfig)
通过继承可以构建公共基础配置,再按环境覆盖差异项。环境切换时只需传入不同的类名,非常优雅。
从 Python 文件加载
如果希望配置独立于代码文件,可以把配置写成 .py 文件,然后用 from_pyfile() 加载:
# config.py
SECRET_KEY = 'file-secret'
MAX_CONTENT_LENGTH = 16 * 1024 * 1024
主应用代码:
app.config.from_pyfile('config.py')
如果文件可能不存在,可以使用 silent=True 防止抛出异常:
app.config.from_pyfile('config.py', silent=True)
该方法也支持 .cfg 等扩展名,但文件内容必须是有效的 Python 语法。
从环境变量加载配置文件路径
你可以把配置文件路径写在一个环境变量中,让应用启动时读取:
# 假设环境变量 APP_SETTINGS=/path/to/production.py
app.config.from_envvar('APP_SETTINGS')
这不直接加载环境变量中的配置项,而是加载该变量指向的文件。如果不设置环境变量,启动会报错,同样可以指定 silent=True。
从环境变量直接加载配置项
如果不想维护配置文件,也可以遍历所有大写环境变量并注入 app.config。常见做法是配合 python-dotenv 使用:
import os
from dotenv import load_dotenv
load_dotenv() # 加载 .env 文件中的环境变量
app.config.update(
SECRET_KEY=os.environ.get('SECRET_KEY'),
DATABASE_URL=os.environ.get('DATABASE_URL'),
DEBUG=os.environ.get('DEBUG', 'False').lower() == 'true'
)
此时项目根目录的 .env 文件长这样:
SECRET_KEY=my-production-secret
DATABASE_URL=postgresql://user:pass@localhost/prod
DEBUG=False
切记 不要将 .env 文件提交到版本库。
从映射(Mapping)加载
如果配置来源是一个字典,可以使用 from_mapping() 方法,它会自动将键转为大写:
app.config.from_mapping(
SECRET_KEY='from-mapping',
SQLALCHEMY_DATABASE_URI='sqlite:///map.db'
)
实例文件夹与相对路径配置
Flask 的“实例文件夹”用于存放需要独立于应用包、且不应受版本控制的文件,例如私有配置或数据库文件。启用实例文件夹后,可以安全地加载其中的配置:
app = Flask(__name__, instance_relative_config=True)
# 从实例文件夹根目录加载 config.py
app.config.from_pyfile('config.py', silent=True)
实例文件夹的默认路径是 instance/,该目录应被添加到 .gitignore 中。
多环境配置的终极实践
下面是一个完整的、清晰的多环境配置模板,集成了类、环境变量与实例文件夹的优势。
- 创建
config.py,定义各个环境的配置类:
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY', 'hard-to-guess-string')
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'mysql+pymysql://user:pass@localhost/prod'
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
- 在应用工厂函数中选择配置:
from flask import Flask
from config import config
def create_app(config_name=None):
if config_name is None:
config_name = os.environ.get('FLASK_ENV', 'default')
app = Flask(__name__)
app.config.from_object(config[config_name])
# 可选:再从实例文件夹加载私密覆盖
app.config.from_pyfile('production_override.py', silent=True)
return app
- 通过环境变量
FLASK_ENV=production或FLASK_ENV=development来决定加载哪个类。这样代码完全不感知具体密钥,所有敏感信息均由环境变量注入。
访问配置项的最佳方式
在应用上下文(视图函数、模板、蓝图)中,推荐使用 current_app.config 而非全局 app 对象,这样更符合模块化设计:
from flask import current_app
def index():
db_uri = current_app.config['SQLALCHEMY_DATABASE_URI']
...
在模板中可以直接使用 config 全局变量:
{% if config['DEBUG'] %}
<!-- 显示调试信息 -->
{% endif %}