web/lib/django/conf/__init__.py
author ymh <ymh.work@gmail.com>
Wed, 02 Jun 2010 18:57:35 +0200
changeset 38 77b6da96e6f1
permissions -rw-r--r--
update django
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
"""
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
Settings and configuration for Django.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
Values will be read from the module specified by the DJANGO_SETTINGS_MODULE environment
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
variable, and then from django.conf.global_settings; see the global settings file for
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
a list of all possible variables.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
"""
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
import os
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
import re
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
import time     # Needed for Windows
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
from django.conf import global_settings
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
from django.utils.functional import LazyObject
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
from django.utils import importlib
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
class LazySettings(LazyObject):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    A lazy proxy for either global Django settings or a custom settings object.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    The user can manually configure settings prior to using them. Otherwise,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
    def _setup(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
        Load the settings module pointed to by the environment variable. This
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
        is used the first time we need any settings at all, if the user has not
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
        previously configured the settings manually.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
        try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
            settings_module = os.environ[ENVIRONMENT_VARIABLE]
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
            if not settings_module: # If it's set but is an empty string.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
                raise KeyError
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
        except KeyError:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
            # NOTE: This is arguably an EnvironmentError, but that causes
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
            # problems with Python's interactive help.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
            raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
        self._wrapped = Settings(settings_module)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
    def configure(self, default_settings=global_settings, **options):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
        Called to manually configure the settings. The 'default_settings'
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
        parameter sets where to retrieve any unspecified values from (its
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
        argument must support attribute access (__getattr__)).
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
        if self._wrapped != None:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
            raise RuntimeError('Settings already configured.')
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
        holder = UserSettingsHolder(default_settings)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
        for name, value in options.items():
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
            setattr(holder, name, value)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
        self._wrapped = holder
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
    def configured(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
        Returns True if the settings have already been configured.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
        return bool(self._wrapped)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
    configured = property(configured)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
class Settings(object):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
    def __init__(self, settings_module):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
        # update this dict from global settings (but only for ALL_CAPS settings)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
        for setting in dir(global_settings):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
            if setting == setting.upper():
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
                setattr(self, setting, getattr(global_settings, setting))
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
        # store the settings module in case someone later cares
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        self.SETTINGS_MODULE = settings_module
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
            mod = importlib.import_module(self.SETTINGS_MODULE)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
        except ImportError, e:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
            raise ImportError("Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e))
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        # Settings that should be converted into tuples if they're mistakenly entered
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
        # as strings.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS")
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
        for setting in dir(mod):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
            if setting == setting.upper():
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
                setting_value = getattr(mod, setting)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
                if setting in tuple_settings and type(setting_value) == str:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
                    setting_value = (setting_value,) # In case the user forgot the comma.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
                setattr(self, setting, setting_value)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
        # Expand entries in INSTALLED_APPS like "django.contrib.*" to a list
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
        # of all those apps.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
        new_installed_apps = []
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        for app in self.INSTALLED_APPS:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
            if app.endswith('.*'):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
                app_mod = importlib.import_module(app[:-2])
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
                appdir = os.path.dirname(app_mod.__file__)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
                app_subdirs = os.listdir(appdir)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
                app_subdirs.sort()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
                name_pattern = re.compile(r'[a-zA-Z]\w*')
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
                for d in app_subdirs:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
                    if name_pattern.match(d) and os.path.isdir(os.path.join(appdir, d)):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
                        new_installed_apps.append('%s.%s' % (app[:-2], d))
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
            else:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
                new_installed_apps.append(app)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
        self.INSTALLED_APPS = new_installed_apps
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        if hasattr(time, 'tzset') and getattr(self, 'TIME_ZONE'):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
            # Move the time zone info into os.environ. See ticket #2315 for why
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
            # we don't do this unconditionally (breaks Windows).
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
            os.environ['TZ'] = self.TIME_ZONE
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
            time.tzset()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
class UserSettingsHolder(object):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
    Holder for user configured settings.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
    # SETTINGS_MODULE doesn't make much sense in the manually configured
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
    # (standalone) case.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
    SETTINGS_MODULE = None
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
    def __init__(self, default_settings):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
        Requests for configuration variables not in this class are satisfied
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
        from the module specified in default_settings (if possible).
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
        """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
        self.default_settings = default_settings
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
    def __getattr__(self, name):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
        return getattr(self.default_settings, name)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
    def __dir__(self):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
        return self.__dict__.keys() + dir(self.default_settings)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
    # For Python < 2.6:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
    __members__ = property(lambda self: self.__dir__())
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
settings = LazySettings()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136