3

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

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

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

目前;

    settings/settings.py

想改成;

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

有没有人设法实现这一目标,或者可能知道实现这一目标的可行解决方案?

4

3 回答 3

4

DJANGO_CONFIGURATION变量引用一个configurations.Configuration子类。如有关使用模式的文档中所述,其想法是用维护多个设置文件的繁琐开销来换取更多 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 引入和删除设置块。
  • 敏感键设置不受源代码控制。

因此,您可以想象制作其中三个文件,每个文件包含三个类,但为什么不只制作一个包含九个类的文件呢?

于 2015-01-31T22:46:01.797 回答
2

您可以设置一个环境变量来指定要使用的设置文件,然后在您的manage.pyandwsgi.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'

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

于 2013-11-12T19:53:29.910 回答
0

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

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 保持不变。

于 2014-07-03T04:08:46.567 回答