【问题标题】:Split configuration files using django-configurations使用 django-configurations 拆分配置文件
【发布时间】:2013-11-25 03:13:07
【问题描述】:

为 Django 构建的包,django-configurations 使用面向对象的模式扩展了基于模块的设置加载。

该包使用DJANGO_SETTINGS_MODULEDJANGO_CONFIGURATION 环境变量来识别设置文件并分别加载适当的配置。

我想将配置(每个对象)拆分为单独的文件,但遇到了困难。

目前;

    settings/settings.py

想改成;

    settings/base.py  
    settings/local.py  
    settings.production.py

有没有人设法做到这一点,或者知道一个可行的解决方案来实现这一点?

【问题讨论】:

    标签: python django configuration split settings


    【解决方案1】:

    DJANGO_CONFIGURATION 变量引用 configurations.Configuration 子类。正如usage patterns 上的文档中所述,我们的想法是用维护多个设置文件的繁琐开销来换取更多 DRYer Mixin/Class 工作流程方案。我知道不得不去更改 manage.pywsgi.py 很烦人,但你会得到很多。

    # example settings.py
    from configurations import Configuration, values
    
    # Build up some mixin classes for related or app-specific settings:
    class AppsMixin(object):
        DJANGO_APPS = (
            'django.contrib.auth', 'django.contrib.contenttypes',
            'django.contrib.sessions', 'django.contrib.messages', 
            'django.contrib.staticfiles', 'django.contrib.sites',
            'django.contrib.flatpages', 'django.contrib.sitemaps',
            'django_extensions'
        )
        ADMIN_APPS = ('filebrowser', 'grappelli', 'django.contrib.admin',)
        DEV_APPS = ('django.contrib.admindocs', 'debug_toolbar',)
        DEFAULT_APPS = (
            'tagging', 'imagekit',
            'tinymce', 'ajax_select',
            'crispy_forms', #...
        )
    
        @property
        def INSTALLED_APPS(self):
            """ Control application ordering dynamically """
            OUT_APPS = self.DJANGO_APPS + self.ADMIN_APPS
            if self.DEBUG:
                OUT_APPS += self.DEV_APPS
            return  OUT_APPS + self.DEFAULT_APPS
    
    class AuthURLMixin(object):
        LOGIN_REDIRECT_URL = 'site-login-success'
        LOGIN_URL = '/auth/login/'
        LOGOUT_URL = '/auth/logout/'
    
    class CrispyFormsMixin(object):
        """ django-crispy-forms specific settings """
        CRISPY_TEMPLATE_PACK = 'bootstrap3'
    
        @property
        def CRISPY_FAIL_SILENTLY(self):
            return not self.DEBUG
    
    class Base(AppsMixin, AuthURLMixin, CrispyFormsMixin, Configuration):
        """ Your equivalent for settings/base.py """
        pass
    
    class Local(Base):
        """ ~ settings/local.py """
        DEBUG = True
        TEMPLATE_DEBUG = DEBUG
        # Custom setting that lets subclasses or your apps
        # check which subclass is active.
        STAGING = False
        # Enable a setting to be defined in os.environ, with a sensible default
        # Don't forget the 'DJANGO_' prefix (e.g. DJANGO_TIME_ZONE) 
        TIME_ZONE = values.Value('America/New_York')
        HTTPS_ONLY = False
        # Stash the secret key in os.environ as DJANGO_SECRET_KEY
        SECRET_KEY = values.SecretValue()
    
        @property
        def CSRF_COOKIE_SECURE(self):
            """ chained dynamic setting """
            return self.HTTPS_ONLY
    
        @property
        def SESSION_COOKIE_SECURE(self):
            """ chained dynamic setting """
            return self.HTTPS_ONLY
    
    class Staging(Local):
        """ This class is used for testing before going production """
        STAGING = True 
        TIME_ZONE = values.Value('America/Phoenix')
        #...
    
    class Prod(Staging):
        """ ~ settings/production.py """
        DEBUG = False
        STAGING = False
        HTTPS_ONLY = True
    

    然后,从您的笔记本电脑:

    /path/to/project/$ python manage.py shell --configuration=Local
    >>>from django.conf import settings
    >>>settings.DEBUG, settings.STAGING, settings.TIME_ZONE
    (True, False, 'America/New_York')    
    

    从您的远程服务器:

    /path/to/remote/project/$ python manage.py shell --configuration=Staging
    >>>from django.conf import settings
    >>>settings.DEBUG, settings.STAGING, settings.TIME_ZONE
    (True, True, 'America/Phoenix')
    

    一切都完美后,进入系统范围:

    # /etc/environment
    DJANGO_SETTINGS_MODULE=thisproject.settings
    DJANGO_CONFIGURATION=Prod
    

    现在三文件问题已经通过一些额外的东西解决了:

    • 动态属性允许您切换或插入任何数字 通过实例方法一次性完成相关设置。
    • 可以通过 mixins 引入和删除设置块。
    • 敏感键设置不受源代码控制。

    所以,您可以制作三个这样的文件,每个包含三个类,但为什么不只制作一个包含九个类的文件呢?

    【讨论】:

      【解决方案2】:

      您可以尝试使用单个设置文件并在其中设置条件。因此,当您在本地运行它时,它设置的参数与远程运行时不同。例如:

      import os
      
      DEVELOPMENT_MODE = not os.path.isfile('/mnt/SERVER')
      
      DEBUG = DEVELOPMENT_MODE
      TEMPLATE_DEBUG = DEBUG
      

      上面检查机器'/mnt/SERVER'上的文件,我的服务器有这个文件,我的笔记本电脑没有。它是一个空文件,只是一个占位符。但它在我的设置中设置了一个标志,我可以这样使用:

      if DEVELOPMENT_MODE:
        CONST_URL = 'http://localhost:8000'
      else:
        CONST_URL = 'http://www.website.com'
      

      我已经用了很多年了,优点是我的 apache、wsgi 和 manage.py 保持不变。

      【讨论】:

        【解决方案3】:

        您可以设置一个环境变量来指定要使用的设置文件,然后在您的manage.pywsgi.py 中执行类似的操作

        config_mode = os.getenv('DJANGO_CONFIG_MODE', 'base')
        
        config_dict = {
            'base': 'settings.base'
            'local': 'settings.local'
            'production': 'settings.production'
        }
        
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', config_dict[config_mode])
        
        # or if you prefer not using a dictionary or if-else blocks, you could
        # set the settings file name you wish to use as the DJANGO_CONFIG_MODE environment
        # variable and use that directly
        
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.{0}'.format(config_mode))
        

        您可能还想在不同的设置文件中指定模式,以便您的代码在不同的模式下表现不同。

        CONFIG_MODE = 'base'   # or 'local' or 'production'
        

        在您的各种设置文件中,并根据需要在您的代码库中使用它。

        【讨论】:

        • 您需要通过添加__init__.py 文件使设置目录成为python 模块。如果你不这样做,你的配置在 python 运行时将不可见。
        • 考虑到OP已经有一个设置目录,里面有一个设置文件,我假设它已经有一个__init__.py
        • 谢谢!修复效果很好的语法错误,有没有一种方法可以在不在 manage.py 中定义 dict 的情况下实现这一点 - 一个更动态的解决方案?
        • 您可以尝试将设置文件的名称设置为环境变量,然后在manage.py(也在wsgi.py)中执行os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.{0}'.format(config_mode))
        猜你喜欢
        • 1970-01-01
        • 2021-05-20
        • 2011-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多