Flask项目配置(Configuration)
shddk
8年前
<p style="text-align: center;"><img src="https://simg.open-open.com/show/dbc23c53b15b1b37cecfe4ad41e73967.png"></p> <p>在Flask项目中,我们会用到很多配置(Config)。比如说设置秘钥,设置数据库地址,像下面这样:</p> <pre> <code class="language-python">... app.config['SECRET_KEY'] = 'some strange words'</code></pre> <p>Flask的配置对象(config)是一个字典的子类(subclass),所以你可以把配置用键值对的方式存储进去。这是一个通用的处理接口,Flask内置的配置,扩展提供的配置,你自己的配置,都集中在一处。</p> <p><strong>为什么需要使用自己的配置?</strong></p> <p>假设你在做一个博客,有十个视图函数都定义了每页显示的文章数。当你写好以后,发现每页的文章太多,想把这个值改小一点,这时你要找到这十个视图函数,分别修改这个值,很蠢吧?使用配置你就使用一行控制所有的变量:</p> <pre> <code class="language-python">app.config['POST_PER_PAGE'] = 12</code></pre> <p>在十个视图函数里使用配置变量代替固定值:</p> <pre> <code class="language-python">post_per_page = app.config['POST_PER_PAGE']</code></pre> <p>其实不就是设置了一个变量嘛……</p> <p>你有两种方式来设置配置:</p> <ol> <li>直接写出配置的值,像上面那样。</li> <li>对于 <strong>不适合写在程序里的配置</strong> ,比如密码等,需要把配置写入系统环境变量,然后使用os模块提供的方法获取:</li> </ol> <pre> <code class="language-python">set MAIL_USERNAME=me@greyli.com # windows export MAIL_USERNAME=me@greyli.com # *unix</code></pre> <p>获取变量并写入:</p> <pre> <code class="language-python">import os from flask import Flask app = Flask(__name__) app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')</code></pre> <p>如果你使用虚拟环境,设置环境变量时注意要激活虚拟环境,同时不要给变量值加引号。</p> <pre> <code class="language-python">set MAIL_USERNAME=me@greyli.com # 结果是'me@greyli.com' set MAIL_USERNAME='me@greyli.com' # 结果是"'me@greyli.com'"</code></pre> <p>你有三种方式来处理配置。</p> <h2><strong>直接写入主脚本</strong></h2> <p>当你的程序很小的时候,可以直接把配置写在主脚本里:</p> <pre> <code class="language-python">from flask import Flask app = Flask(__name__) app.config['SECRET_KEY'] = 'some secret words' app.config['DEBUG'] = True app.config['ITEMS_PER_PAGE'] = 10</code></pre> <p>使用字典的update方法可以简化代码:</p> <pre> <code class="language-python">from flask import Flask app = Flask(__name__) app.config.update( DEBUG=True, SECRET_KEY='some secret words', ITEMS_PER_PAGE=10 )</code></pre> <h2><strong>单独的配置文件</strong></h2> <p>程序逐渐变大时,配置也逐渐增多,写在主脚本里太占地方,不够优雅(这时你应该已经把表单,路由,数据库模型等等分成独立的文件了。关于大型项目结构,后续会总结)。我们可以创建一个单独的配置文件。和上面同样的配置,现在可以改写为:</p> <p>config.py</p> <pre> <code class="language-python">SECRET_KEY = 'some secret words' DEBUG = True ITEMS_PER_PAGE = 10</code></pre> <p>在创建程序实例后导入配置:</p> <pre> <code class="language-python">import config ... app = Flask(__name__) app.config.from_object(config) ...</code></pre> <h2><strong>创建不同的配置类</strong></h2> <p>大型项目需要多个配置组合,比如开发时的配置,测试的配置,部署的配置……这样我们需要在配置文件里创建不同的配置类,然后在创建程序实例时引入相应的配置类。</p> <p>最佳实践是创建一个 <strong>存储通用配置</strong> 的基类,然后为不同的使用使用场景创建新的继承基类的配置类:</p> <p>config.py(这里为开发和测试创建了不同的数据库)</p> <pre> <code class="language-python">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 }</code></pre> <p>通过from_object()方法导入配置:</p> <pre> <code class="language-python">from config import config # 导入存储配置的字典 ... app = Flask(__name__) app.config.from_object(config['development']) # 获取相应的配置类 ...</code></pre> <p>关于大型项目结构,扩展的初始化,使用程序工厂函数创建程序实例等内容见后续。</p> <h2><strong>相关链接</strong></h2> <ul> <li>Flask的内置配置值: <a href="/misc/goto?guid=4959727488485968042" rel="nofollow,noindex"> http:// flask.pocoo.org/docs/0. 11/config/#builtin-configuration-values </a></li> <li>Flask配置文档: <a href="/misc/goto?guid=4959727488575687544" rel="nofollow,noindex"> http:// flask.pocoo.org/docs/0. 11/config/#configuration-handling </a></li> <li>《Flask Web开发》中的配置文件: <a href="/misc/goto?guid=4959727488650951003" rel="nofollow,noindex"> https:// github.com/greyli/flask y/blob/master/config.py </a></li> </ul> <p> </p> <p> </p> <p>来自:https://zhuanlan.zhihu.com/p/24055329</p> <p> </p>