Django

Code

Changeset 2927

Show
Ignore:
Timestamp:
05/16/06 16:28:06 (2 years ago)
Author:
adrian
Message:

Fixed #1321 -- Made DJANGO_SETTINGS_MODULE optional. You can now call django.conf.settings.configure() to set settings manually if you don't have a settings module. Thanks, Malcolm Tredinnick, Luke Plant, Fredrik Lundh

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/conf/__init__.py

    r2809 r2927  
    1313ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" 
    1414 
     15class LazySettings: 
     16    """ 
     17    A lazy proxy for either global Django settings or a custom settings object. 
     18    The user can manually configure settings prior to using them. Otherwise, 
     19    Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE. 
     20    """ 
     21    def __init__(self): 
     22        # _target must be either None or something that supports attribute 
     23        # access (getattr, hasattr, etc). 
     24        self._target = None 
     25 
     26    def __getattr__(self, name): 
     27        if self._target is None: 
     28            self._import_settings() 
     29        if name == '__members__': 
     30            # Used to implement dir(obj), for example. 
     31            return self._target.get_all_members() 
     32        return getattr(self._target, name) 
     33 
     34    def __setattr__(self, name, value): 
     35        if name == '_target': 
     36            self.__dict__['_target'] = value 
     37        else: 
     38            setattr(self._target, name, value) 
     39 
     40    def _import_settings(self): 
     41        """ 
     42        Load the settings module pointed to by the environment variable. This 
     43        is used the first time we need any settings at all, if the user has not 
     44        previously configured the settings manually. 
     45        """ 
     46        try: 
     47            settings_module = os.environ[ENVIRONMENT_VARIABLE] 
     48            if not settings_module: # If it's set but is an empty string. 
     49                raise KeyError 
     50        except KeyError: 
     51            raise EnvironmentError, "Environment variable %s is undefined." % ENVIRONMENT_VARIABLE 
     52 
     53        self._target = Settings(settings_module) 
     54 
     55    def configure(self, default_settings=global_settings, **options): 
     56        """ 
     57        Called to manually configure the settings. The 'default_settings' 
     58        parameter sets where to retrieve any unspecified values from (its 
     59        argument must support attribute access (__getattr__)). 
     60        """ 
     61        if self._target != None: 
     62            raise EnvironmentError, 'Settings already configured.' 
     63        holder = UserSettingsHolder(default_settings) 
     64        for name, value in options.items(): 
     65            setattr(holder, name, value) 
     66        self._target = holder 
     67 
    1568class Settings: 
    16  
    1769    def __init__(self, settings_module): 
    18  
    1970        # update this dict from global settings (but only for ALL_CAPS settings) 
    2071        for setting in dir(global_settings): 
     
    2879            mod = __import__(self.SETTINGS_MODULE, '', '', ['']) 
    2980        except ImportError, e: 
    30             raise EnvironmentError, "Could not import settings '%s' (is it on sys.path?): %s" % (self.SETTINGS_MODULE, e) 
     81            raise EnvironmentError, "Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e) 
    3182 
    3283        # Settings that should be converted into tuples if they're mistakenly entered 
     
    57108        os.environ['TZ'] = self.TIME_ZONE 
    58109 
    59 # try to load DJANGO_SETTINGS_MODULE 
    60 try: 
    61     settings_module = os.environ[ENVIRONMENT_VARIABLE] 
    62     if not settings_module: # If it's set but is an empty string. 
    63         raise KeyError 
    64 except KeyError: 
    65     raise EnvironmentError, "Environment variable %s is undefined." % ENVIRONMENT_VARIABLE 
     110    def get_all_members(self): 
     111        return dir(self) 
    66112 
    67 # instantiate the configuration object 
    68 settings = Settings(settings_module) 
     113class UserSettingsHolder: 
     114    """ 
     115    Holder for user configured settings. 
     116    """ 
     117    # SETTINGS_MODULE does not really make sense in the manually configured 
     118    # (standalone) case. 
     119    SETTINGS_MODULE = None 
     120 
     121    def __init__(self, default_settings): 
     122        """ 
     123        Requests for configuration variables not in this class are satisfied 
     124        from the module specified in default_settings (if possible). 
     125        """ 
     126        self.default_settings = default_settings 
     127 
     128    def __getattr__(self, name): 
     129        return getattr(self.default_settings, name) 
     130 
     131    def get_all_members(self): 
     132        return dir(self) + dir(self.default_settings) 
     133 
     134settings = LazySettings() 
    69135 
    70136# install the translation machinery so that it is available 
    71137from django.utils import translation 
    72138translation.install() 
    73  
  • django/trunk/django/template/defaultfilters.py

    r2905 r2927  
    328328################### 
    329329 
    330 def date(value, arg=settings.DATE_FORMAT): 
     330def date(value, arg=None): 
    331331    "Formats a date according to the given format" 
    332332    from django.utils.dateformat import format 
     333    if arg is None: 
     334        arg = settings.DATE_FORMAT 
    333335    return format(value, arg) 
    334336 
    335 def time(value, arg=settings.TIME_FORMAT): 
     337def time(value, arg=None): 
    336338    "Formats a time according to the given format" 
    337339    from django.utils.dateformat import time_format 
     340    if arg is None: 
     341        arg = settings.TIME_FORMAT 
    338342    return time_format(value, arg) 
    339343 
     
    436440    except Exception, e: 
    437441        return "Error in formatting:%s" % e 
    438      
     442 
    439443# Syntax: register.filter(name of filter, callback) 
    440444register.filter(add) 
  • django/trunk/django/utils/translation.py

    r2911 r2927  
    118118    globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale') 
    119119 
    120     parts = settings.SETTINGS_MODULE.split('.') 
    121     project = __import__(parts[0], {}, {}, []) 
    122     projectpath = os.path.join(os.path.dirname(project.__file__), 'locale') 
     120    if settings.SETTINGS_MODULE is not None: 
     121        parts = settings.SETTINGS_MODULE.split('.') 
     122        project = __import__(parts[0], {}, {}, []) 
     123        projectpath = os.path.join(os.path.dirname(project.__file__), 'locale') 
     124    else: 
     125        projectpath = None 
    123126 
    124127    def _fetch(lang, fallback=None): 
     
    156159                    res = _merge(localepath) 
    157160 
    158         if os.path.isdir(projectpath): 
     161        if projectpath and os.path.isdir(projectpath): 
    159162            res = _merge(projectpath) 
    160163 
  • django/trunk/docs/i18n.txt

    r2809 r2927  
    540540a big project out of several apps and put all translations into one big project 
    541541message file. The choice is yours. 
     542 
     543.. note:: 
     544 
     545    If you're using manually configured settings, as described in the 
     546    `settings documentation`_, the ``locale`` directory in the project 
     547    directory will not be examined, since Django loses the ability to work out 
     548    the location of the project directory. (Django normally uses the location 
     549    of the settings file to determine this, and a settings file doesn't exist 
     550    if you're manually configuring your settings.) 
     551 
     552.. _settings documentation: http://www.djangoproject.com/documentation/settings/#using-settings-without-the-django-settings-module-environment-variable 
    542553 
    543554All message file repositories are structured the same way. They are: 
  • django/trunk/docs/settings.txt

    r2809 r2927  
    725725      purely for performance. 
    726726    * Don't reinvent an already-existing setting. 
     727 
     728Using settings without setting DJANGO_SETTINGS_MODULE 
     729===================================================== 
     730 
     731In some cases, you might want to bypass the ``DJANGO_SETTINGS_MODULE`` 
     732environment variable. For example, if you're using the template system by 
     733itself, you likely don't want to have to set up an environment variable 
     734pointing to a settings module. 
     735 
     736In these cases, you can configure Django's settings manually. Do this by 
     737calling ``django.conf.settings.configure()``. 
     738 
     739Example:: 
     740 
     741    from django.conf import settings 
     742 
     743    settings.configure(DEBUG=True, TEMPLATE_DEBUG=True, 
     744        TEMPLATE_DIRS=('/home/web-apps/myapp', '/home/web-apps/base')) 
     745 
     746Pass ``configure()`` as many keyword arguments as you'd like, with each keyword 
     747argument representing a setting and its value. Each argument name should be all 
     748uppercase, with the same name as the settings described above. If a particular 
     749setting is not passed to ``configure()`` and is needed at some later point, 
     750Django will use the default setting value. 
     751 
     752Custom default settings 
     753----------------------- 
     754 
     755If you'd like default values to come from somewhere other than 
     756``django.conf.global_settings``, you can pass in a module or class that 
     757provides the default settings as the ``default_settings`` argument (or as the 
     758first positional argument) in the call to ``configure()``. 
     759 
     760In this example, default settings are taken from ``myapp_defaults``, and the 
     761``DEBUG`` setting is set to ``True``, regardless of its value in 
     762``myapp_defaults``:: 
     763 
     764    from django.conf import settings 
     765    from myapp import myapp_defaults 
     766 
     767    settings.configure(default_settings=myapp_defaults, DEBUG=True) 
     768 
     769The following example, which uses ``myapp_defaults`` as a positional argument, 
     770is equivalent:: 
     771 
     772    settings.configure(myapp_defaults, DEBUG = True) 
     773 
     774Either configure() or DJANGO_SETTINGS_MODULE is required 
     775-------------------------------------------------------- 
     776 
     777If you're not setting the ``DJANGO_SETTINGS_MODULE`` environment variable, you 
     778*must* call ``configure()`` at some point before using any code that reads 
     779settings. 
     780 
     781If you don't set ``DJANGO_SETTINGS_MODULE`` and don't call ``configure()``, 
     782Django will raise an ``EnvironmentError`` exception the first time a setting 
     783is accessed. 
     784 
     785If you set ``DJANGO_SETTINGS_MODULE``, access settings values somehow, *then* 
     786call ``configure()``, Django will raise an ``EnvironmentError`` saying settings 
     787have already been configured. 
     788 
     789Also, it's an error to call ``configure()`` more than once, or to call 
     790``configure()`` after any setting has been accessed. 
     791 
     792It boils down to this: Use exactly one of either ``configure()`` or 
     793``DJANGO_SETTINGS_MODULE``. Not both, and not neither. 
  • django/trunk/docs/templates_python.txt

    r2809 r2927  
    77reference on the language syntax, see 
    88`The Django template language: For template authors`_. 
     9 
     10If you're looking to use the Django template system as part of another 
     11application -- i.e., without the rest of the framework -- make sure to read 
     12the `configuration`_ section later in this document. 
    913 
    1014.. _`The Django template language: For template authors`: http://www.djangoproject.com/documentation/templates/ 
     
    877881``{% for %}``, ``{% ifequal %}`` and ``{% ifchanged %}``. They live in 
    878882``django/template/defaulttags.py``. 
     883 
     884.. _configuration: 
     885 
     886Configuring the template system in standalone mode 
     887================================================== 
     888 
     889.. note:: 
     890 
     891    This section is only of interest to people trying to use the template 
     892    system as an output component in another application. If you are using the 
     893    template system as part of a Django application, nothing here applies to 
     894    you. 
     895 
     896Normally, Django will load all the configuration information it needs from its 
     897own default configuration file, combined with the settings in the module given 
     898in the ``DJANGO_SETTINGS_MODULE`` environment variable. But if you're using the 
     899template system independently of the rest of Django, the environment variable 
     900approach isn't very convenient, because you probably want to configure the 
     901template system in line with the rest of your application rather than dealing 
     902with settings files and pointing to them via environment variables. 
     903 
     904To solve this problem, you need to use the manual configuration option 
     905described in the `settings file`_ documentation. Simply import the appropriate 
     906pieces of the templating system and then, *before* you call any of the 
     907templating functions, call ``django.conf.settings.configure()`` with any 
     908settings you wish to specify. You might want to consider setting at least 
     909``TEMPLATE_DIRS`` (if you are going to use template loaders), 
     910``DEFAULT_CHARSET`` (although the default of ``utf-8`` is probably fine) and 
     911``TEMPLATE_DEBUG``. All available settings are described in the 
     912`settings documentation`_, and any setting starting with *TEMPLATE_* 
     913is of obvious interest. 
     914 
     915.. _settings file: http://www.djangoproject.com/documentation/settings/#using-settings-without-the-django-settings-module-environment-variable 
     916.. _settings documentation: http://www.djangoproject.com/documentation/settings/ 
  • django/trunk/tests/othertests/templates.py

    r2809 r2927  
    508508 
    509509if __name__ == "__main__": 
     510    settings.configure() 
    510511    run_tests(1, True) 
  • django/trunk/tests/runtests.py

    r2809 r2927  
    7373    def run_tests(self): 
    7474        from django.conf import settings 
     75 
     76        # An empty access of the settings to force the default options to be 
     77        # installed prior to assigning to them. 
     78        settings.INSTALLED_APPS 
    7579 
    7680        # Manually set INSTALLED_APPS to point to the test models.