2006-05-02 09:31:56 +08:00
"""
Settings and configuration for Django .
Values will be read from the module specified by the DJANGO_SETTINGS_MODULE environment
variable , and then from django . conf . global_settings ; see the global settings file for
a list of all possible variables .
"""
import os
2007-02-12 08:10:09 +08:00
import time # Needed for Windows
2006-05-02 09:31:56 +08:00
from django . conf import global_settings
ENVIRONMENT_VARIABLE = " DJANGO_SETTINGS_MODULE "
2006-06-08 13:00:13 +08:00
class LazySettings ( object ) :
2006-05-17 05:28:06 +08:00
"""
A lazy proxy for either global Django settings or a custom settings object .
The user can manually configure settings prior to using them . Otherwise ,
Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE .
"""
def __init__ ( self ) :
# _target must be either None or something that supports attribute
# access (getattr, hasattr, etc).
self . _target = None
def __getattr__ ( self , name ) :
if self . _target is None :
self . _import_settings ( )
if name == ' __members__ ' :
# Used to implement dir(obj), for example.
return self . _target . get_all_members ( )
return getattr ( self . _target , name )
def __setattr__ ( self , name , value ) :
if name == ' _target ' :
2006-05-17 10:02:26 +08:00
# Assign directly to self.__dict__, because otherwise we'd call
# __setattr__(), which would be an infinite loop.
2006-05-17 05:28:06 +08:00
self . __dict__ [ ' _target ' ] = value
else :
2007-07-16 12:45:45 +08:00
if self . _target is None :
self . _import_settings ( )
2006-05-17 05:28:06 +08:00
setattr ( self . _target , name , value )
def _import_settings ( self ) :
"""
Load the settings module pointed to by the environment variable . This
is used the first time we need any settings at all , if the user has not
previously configured the settings manually .
"""
try :
settings_module = os . environ [ ENVIRONMENT_VARIABLE ]
if not settings_module : # If it's set but is an empty string.
raise KeyError
except KeyError :
2007-12-02 23:27:44 +08:00
raise ImportError , " Environment variable %s is undefined so settings cannot be imported. " % ENVIRONMENT_VARIABLE # NOTE: This is arguably an EnvironmentError, but that causes problems with Python's interactive help
2006-05-17 05:28:06 +08:00
self . _target = Settings ( settings_module )
def configure ( self , default_settings = global_settings , * * options ) :
"""
Called to manually configure the settings . The ' default_settings '
parameter sets where to retrieve any unspecified values from ( its
argument must support attribute access ( __getattr__ ) ) .
"""
if self . _target != None :
2007-12-02 23:27:44 +08:00
raise RuntimeError , ' Settings already configured. '
2006-05-17 05:28:06 +08:00
holder = UserSettingsHolder ( default_settings )
for name , value in options . items ( ) :
setattr ( holder , name , value )
self . _target = holder
2006-05-02 09:31:56 +08:00
2006-06-08 13:00:13 +08:00
class Settings ( object ) :
2006-05-02 09:31:56 +08:00
def __init__ ( self , settings_module ) :
# update this dict from global settings (but only for ALL_CAPS settings)
for setting in dir ( global_settings ) :
if setting == setting . upper ( ) :
setattr ( self , setting , getattr ( global_settings , setting ) )
# store the settings module in case someone later cares
self . SETTINGS_MODULE = settings_module
try :
2006-10-31 04:50:27 +08:00
mod = __import__ ( self . SETTINGS_MODULE , { } , { } , [ ' ' ] )
2006-05-02 09:31:56 +08:00
except ImportError , e :
2007-12-02 23:27:44 +08:00
raise ImportError , " Could not import settings ' %s ' (Is it on sys.path? Does it have syntax errors?): %s " % ( self . SETTINGS_MODULE , e )
2006-05-02 09:31:56 +08:00
# Settings that should be converted into tuples if they're mistakenly entered
# as strings.
tuple_settings = ( " INSTALLED_APPS " , " TEMPLATE_DIRS " )
for setting in dir ( mod ) :
if setting == setting . upper ( ) :
setting_value = getattr ( mod , setting )
if setting in tuple_settings and type ( setting_value ) == str :
setting_value = ( setting_value , ) # In case the user forgot the comma.
setattr ( self , setting , setting_value )
# Expand entries in INSTALLED_APPS like "django.contrib.*" to a list
# of all those apps.
new_installed_apps = [ ]
for app in self . INSTALLED_APPS :
if app . endswith ( ' .* ' ) :
2006-10-31 04:50:27 +08:00
appdir = os . path . dirname ( __import__ ( app [ : - 2 ] , { } , { } , [ ' ' ] ) . __file__ )
2006-05-02 09:31:56 +08:00
for d in os . listdir ( appdir ) :
if d . isalpha ( ) and os . path . isdir ( os . path . join ( appdir , d ) ) :
new_installed_apps . append ( ' %s . %s ' % ( app [ : - 2 ] , d ) )
else :
new_installed_apps . append ( app )
self . INSTALLED_APPS = new_installed_apps
2007-02-12 08:10:09 +08:00
if hasattr ( time , ' tzset ' ) :
# Move the time zone info into os.environ. See ticket #2315 for why
# we don't do this unconditionally (breaks Windows).
os . environ [ ' TZ ' ] = self . TIME_ZONE
2007-09-16 02:11:43 +08:00
time . tzset ( )
2006-05-02 09:31:56 +08:00
2006-05-17 05:28:06 +08:00
def get_all_members ( self ) :
return dir ( self )
2006-06-08 13:00:13 +08:00
class UserSettingsHolder ( object ) :
2006-05-17 05:28:06 +08:00
"""
Holder for user configured settings .
"""
2006-07-04 11:58:45 +08:00
# SETTINGS_MODULE doesn't make much sense in the manually configured
2006-05-17 05:28:06 +08:00
# (standalone) case.
SETTINGS_MODULE = None
2006-05-02 09:31:56 +08:00
2006-05-17 05:28:06 +08:00
def __init__ ( self , default_settings ) :
"""
Requests for configuration variables not in this class are satisfied
from the module specified in default_settings ( if possible ) .
"""
self . default_settings = default_settings
def __getattr__ ( self , name ) :
return getattr ( self . default_settings , name )
def get_all_members ( self ) :
return dir ( self ) + dir ( self . default_settings )
settings = LazySettings ( )
2006-05-02 09:31:56 +08:00