• 用flask开发个人博客(26)—— 利用config.py配置文件动态的创建不同的Flask对象


    原文:https://blog.csdn.net/hyman_c/article/details/52877704

            对配置进行封装的目的是根据不同的使用场景,给flask的app赋予不同的config,最经典的用法就是把开发、测试和生成分开,通过配置文件使用不同的数据库。


    config.py代码如下:
          
    1.  
      import os
    2.  
      basedir = os.path.abspath(os.path.dirname(__file__))
    3.  
       
    4.  
      class Config:
    5.  
      SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
    6.  
      SQLALCHEMY_COMMIT_ON_TEARDOWN = True
    7.  
      FLASKY_MAIL_SUBJECT_PREFIX='[Flasky]'
    8.  
      FLASKY_MAIL_SENDER = '879651072@qq.com'
    9.  
      FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')
    10.  
       
    11.  
      @staticmethod
    12.  
      def init_app(app):
    13.  
      pass
    14.  
       
    15.  
      class DevelopmentConfig(Config):
    16.  
      DEBUG = True
    17.  
      MAIL_SERVER = 'smtp.qq.com'
    18.  
      MAIL_PORT = 587
    19.  
      MAIL_USE_TLS = True
    20.  
      MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
    21.  
      MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
    22.  
      SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URI') or
    23.  
      'sqlite:///' + os.path.join(basedir,'data-dev.sqlite')
    24.  
       
    25.  
      class TestingConfig(Config):
    26.  
      TESTING = True
    27.  
      SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URI') or
    28.  
      'sqlite:///' + os.path.join(basedir,'data-test.sqlite')
    29.  
       
    30.  
      class ProductionConfig(Config):
    31.  
      SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI') or
    32.  
      'sqlite:///' + os.path.join(basedir,'data.sqlite')
    33.  
       
    34.  
      config={
    35.  
      'development':DevelopmentConfig,
    36.  
      'testing':TestingConfig,
    37.  
      'Production':ProductionConfig,
    38.  
      'default':DevelopmentConfig
    39.  
      }

            现在来分析一下整个config.py的代码结构,首先定义了一个基类Config,该类中包含了在开发,测试和生产配置都需要的基本配置,其中包包括预防CSRF的密钥、设置数据库自动commit的选项等等,其他开发、测试和生产配置分别从Config继承,主要区别在于配置的数据库路径不一样。

              最后定义了一个config的字典,作为外部调用这些配置的接口。下面我们看下怎么去调用这些配置,这里我先引入了app/__init__.py这个app包的构造文件:

    1.  
      from flask import Flask,render_template
    2.  
      from flask.ext.bootstrap import Bootstrap
    3.  
      from flask.ext.mail import Mail
    4.  
      from flask.ext.moment import Moment
    5.  
      from flask.ext.sqlalchemy import SQLAlchemy
    6.  
      from config import config
    7.  
       
    8.  
      bootstrap=Bootstrap()
    9.  
      mail=Mail()
    10.  
      moment=Moment()
    11.  
      db=SQLAlchemy()
    12.  
       
    13.  
      def create_app(config_name):
    14.  
      app=Flask(__name__)
    15.  
      app.config.from_object(config[config_name])
    16.  
      config[config_name].init_app(app)
    17.  
       
    18.  
      bootstrap.init_app(app)
    19.  
      mail.init_app(app)
    20.  
      moment.init_app(app)
    21.  
      db.init_app(app)
    22.  
       
    23.  
      from .main import main as main_blueprint
    24.  
      app.register_blueprint(main_blueprint)
    25.  
      return app

        请注意下面这三行代码,第一行是从我们定义的config.py中引入config这个字典;第二行是通过config_name获取不同的Config子类对象,app.config的from_object函数会对返回的Config对象的子类提取相关属性和值,稍后我会详细分析下这个方法;第三行调用init_app()这个静态方法对app进行其他的操作,但是我们这里用了pass,并没有做实际的操作。到此为止,只用了三行代码便实现了对config的调用。
    from config import config
    1.  
      app.config.from_object(config[config_name])
    2.  
      config[config_name].init_app(app)

            下面我分析下app.config.from_object()这个函数,最开始时为了测试这个函数的作用,我定义了下面的类:

    1.  
      class Myobj:
    2.  
      name='hyman'

            调用app.config.from_object(Myobj)的方法,发现app的config中并没有正确引入name并赋值‘hyman’,后面查看了它的源代码():
    1.  
      def from_object:
    2.  
      if isinstance(obj, string_types):
    3.  
      obj = import_string(obj)
    4.  
      for key in dir(obj):
    5.  
      if key.isupper():
    6.  
      self[key] = getattr(obj, key)
            发现了原来他有if key.isupper()的判断,也就是说必须是大写字母的属性它才会进行引入,它引入的方法就是调用通过python标准的api getattr()函数,将Myobj的属性改成大写后读取Myobj的NAME属性并获取其值正常。

    Github位置:
    https://github.com/HymanLiuTS/flaskTs

    克隆本项目:
    git clone git@github.com:HymanLiuTS/flaskTs.git
    获取本文源代码:
    git checkout FL26
  • 相关阅读:
    Java基本数据类型之间转换
    python 元组tuple
    python 列表List
    python 字符串
    python for循环
    python break/continue
    python while循环
    python条件判断if/else
    python运算符
    python变量
  • 原文地址:https://www.cnblogs.com/zhaohuanhuan/p/9480389.html
Copyright © 2020-2023  润新知