2.Flask配置
我们都知道,Flask应用程序肯定是需要各种各样的配置。来满足我们不同的需求的,这样可以使我们的应用程序更加灵活。比如可以根据需要更改不同的配置,比如调试模式开关、 密钥、数据库等。
在Flask中,有一个配置对象用来维持加载的配置值:Flask的 config 对象。 这是Flask自身放置特定配置的地方,同时也是扩展放置它们配置值的地方。但是,这里也可以放置你自己的配置 。config
实际上是字典的一个子类且能够像字典一样被修改 。
Flask中,设置自己的配置有以下几种方式。
2.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.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')
如果你使用虚拟环境,设置环境变量时注意要激活虚拟环境,同时不要给变量值加引号:
set MAIL_USERNAME=me@greyli.com # 结果是'me@greyli.com'
set MAIL_USERNAME='me@greyli.com' # 结果是"'me@greyli.com'"
2.3 单独的配置文件
程序逐渐变大时,配置也逐渐增多,写在主脚本里太占地方,不够优雅,这时你应该已经把表单,路由,数据库模型等等分成独立的文件了,如下,创建config.py文件。
config.py
SECRET_KEY = 'some secret words'
DEBUG = True
ITEMS_PER_PAGE = 10
在创建程序实例后使用app.config.from_object
导入配置:
from flask import Flask
import config
app = Flask(__name__)
app.config.from_object(config)
# print(app.config['SECRET_KEY'])
# print(app.config['ITEMS_PER_PAGE'])
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
或使用app.config.from_pyfile
导入配置:
from flask import Flask
import config
app = Flask(__name__)
app.config.from_pyfile('config.py')
print(app.config['SECRET_KEY'])
print(app.config['ITEMS_PER_PAGE'])
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
2.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
SECRET_KEY = 'afasjkfnasfhas'
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 flask import Flask
from config import config
app = Flask(__name__)
# app.config.from_object(config)
# app.config.from_pyfile('config.py')
app.config.from_object(config['development'])
print(app.config['SECRET_KEY'])
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
2.5 Flask内置配置
Flask中有许多配置,一般我们没有自己配置的话,都是使用它提供的默认配置,Flask中所有的内置配置如下:
{
'DEBUG': False, # 是否开启Debug模式
'TESTING': False, # 是否开启测试模式
'PROPAGATE_EXCEPTIONS': None, # 异常传播(是否在控制台打印LOG) 当Debug或者testing开启后,自动为True
'PRESERVE_CONTEXT_ON_EXCEPTION': None, # 一两句话说不清楚,一般不用它
'SECRET_KEY': None, # 之前遇到过,在启用Session的时候,一定要有它
'PERMANENT_SESSION_LIFETIME': 31, # days , Session的生命周期(天)默认31天
'USE_X_SENDFILE': False, # 是否弃用 x_sendfile
'LOGGER_NAME': None, # 日志记录器的名称
'LOGGER_HANDLER_POLICY': 'always',
'SERVER_NAME': None, # 服务访问域名
'APPLICATION_ROOT': None, # 项目的完整路径
'SESSION_COOKIE_NAME': 'session', # 在cookies中存放session加密字符串的名字
'SESSION_COOKIE_DOMAIN': None, # 在哪个域名下会产生session记录在cookies中
'SESSION_COOKIE_PATH': None, # cookies的路径
'SESSION_COOKIE_HTTPONLY': True, # 控制 cookie 是否应被设置 httponly 的标志,
'SESSION_COOKIE_SECURE': False, # 控制 cookie 是否应被设置安全标志
'SESSION_REFRESH_EACH_REQUEST': True, # 这个标志控制永久会话如何刷新
'MAX_CONTENT_LENGTH': None, # 如果设置为字节数, Flask 会拒绝内容长度大于此值的请求进入,并返回一个 413 状态码
'SEND_FILE_MAX_AGE_DEFAULT': 12, # hours 默认缓存控制的最大期限
'TRAP_BAD_REQUEST_ERRORS': False,
# 如果这个值被设置为 True ,Flask不会执行 HTTP 异常的错误处理,而是像对待其它异常一样,
# 通过异常栈让它冒泡地抛出。这对于需要找出 HTTP 异常源头的可怕调试情形是有用的。
'TRAP_HTTP_EXCEPTIONS': False,
# Werkzeug 处理请求中的特定数据的内部数据结构会抛出同样也是“错误的请求”异常的特殊的 key errors 。
# 同样地,为了保持一致,许多操作可以显式地抛出 BadRequest 异常。
# 因为在调试中,你希望准确地找出异常的原因,这个设置用于在这些情形下调试。
# 如果这个值被设置为 True ,你只会得到常规的回溯。
'EXPLAIN_TEMPLATE_LOADING': False,
'PREFERRED_URL_SCHEME': 'http', # 生成URL的时候如果没有可用的 URL 模式话将使用这个值
'JSON_AS_ASCII': True,
# 默认情况下 Flask 使用 ascii 编码来序列化对象。如果这个值被设置为 False ,
# Flask不会将其编码为 ASCII,并且按原样输出,返回它的 unicode 字符串。
# 比如 jsonfiy 会自动地采用 utf-8 来编码它然后才进行传输。
'JSON_SORT_KEYS': True,
#默认情况下 Flask 按照 JSON 对象的键的顺序来序来序列化它。
# 这样做是为了确保键的顺序不会受到字典的哈希种子的影响,从而返回的值每次都是一致的,不会造成无用的额外 HTTP 缓存。
# 你可以通过修改这个配置的值来覆盖默认的操作。但这是不被推荐的做法因为这个默认的行为可能会给你在性能的代价上带来改善。
'JSONIFY_PRETTYPRINT_REGULAR': True,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
}
参考:
https://zhuanlan.zhihu.com/p/24055329
https://www.jianshu.com/p/f1d341119df0?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
http://www.pythondoc.com/flask/config.html