Ticket #1321: standalone-django.diff

File standalone-django.diff, 13.2 KB (added by Malcolm Tredinnick <malcolm@…>, 18 years ago)

An updated version of Luke's patch that tries to work for all cases.

  • django/conf/__init__.py

     
    1212
    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 the
     19    standard settings, 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
     68
    1569class Settings:
    1670
    1771    def __init__(self, settings_module):
     
    56110        # move the time zone info into os.environ
    57111        os.environ['TZ'] = self.TIME_ZONE
    58112
    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
     113    def get_all_members(self):
     114        return dir(self)
    66115
    67 # instantiate the configuration object
    68 settings = Settings(settings_module)
     116class UserSettingsHolder:
     117    """
     118    Holder for user configured settings.
     119    """
     120    # SETTINGS_MODULE does not really make sense in the manually configured
     121    # (standalone) case.
     122    SETTINGS_MODULE = None
    69123
     124    def __init__(self, default_settings):
     125        """
     126        Requests for configuration variables not in this class are satisfied
     127        from the module specified in default_settings (if possible).
     128        """
     129        self.default_settings = default_settings
     130
     131    def __getattr__(self, name):
     132        return getattr(self.default_settings, name)
     133
     134    def get_all_members(self):
     135        return dir(self) + dir(self.default_settings)
     136
     137settings = LazySettings()
     138
    70139# install the translation machinery so that it is available
    71140from django.utils import translation
    72141translation.install()
  • django/utils/translation.py

     
    117117
    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):
    125128
     
    155158                if os.path.isdir(localepath):
    156159                    res = _merge(localepath)
    157160
    158         if os.path.isdir(projectpath):
     161        if projectpath and os.path.isdir(projectpath):
    159162            res = _merge(projectpath)
    160163
    161164        for appname in settings.INSTALLED_APPS:
  • django/template/defaultfilters.py

     
    327327# DATES           #
    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
    340344def timesince(value):
  • tests/othertests/templates.py

     
    507507        raise Exception, msg
    508508
    509509if __name__ == "__main__":
     510    settings.configure()
    510511    run_tests(1, True)
  • tests/runtests.py

     
    7373    def run_tests(self):
    7474        from django.conf import settings
    7575
     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
     79
    7680        # Manually set INSTALLED_APPS to point to the test models.
    7781        settings.INSTALLED_APPS = [MODEL_TESTS_DIR_NAME + '.' + a for a in get_test_models()]
    7882
  • docs/settings.txt

     
    724724    * For settings that are sequences, use tuples instead of lists. This is
    725725      purely for performance.
    726726    * Don't reinvent an already-existing setting.
     727
     728Using settings without the DJANGO_SETTINGS_MODULE environment variable
     729=======================================================================
     730
     731In some very special circumstances, it is not appropriate to read the
     732configuration module's name from an environment variable. For example, if you
     733are using the templating or view system as part of another system, without
     734running a full Django setup, you will want to be able to import the
     735appropriate subsystem and configure it just before you use it.
     736
     737In these cases, you can configure Django's settings manually (and, indeed, you
     738*must* do so if you are not setting the DJANGO_SETTINGS_MODULE environment
     739variable). The ``configure()`` method in ``django.conf.settings`` is the way
     740to do this.
     741
     742.. note::
     743
     744    You must call ``configure()`` prior to running any method that uses the
     745    settings or reading any attributes from ``django.conf.settings`` yourself.
     746    As soon as anything accesses ``django.conf.settings``, the module
     747    specified in ``DJANGO_SETTINGS_MODULE`` is loaded, unless you have
     748    previously called ``configure()`` and an error results if the environment
     749    variable is not set correctly.
     750
     751    It is an error to call ``configure()`` more than once or to call
     752    ``configure()`` after any setting has been accessed. This is in line with
     753    the admonishment earlier in this document about not writing to
     754    ``settings`` at all. Configure your settings early and then leave them
     755    fixed.
     756
     757The call to ``configure()`` takes any number of keyword arguments specifying
     758settings and their values. These keywords are all uppercase values with the
     759same names as the settings described above. If a particular setting is not
     760passed to ``configure()`` and is needed at some later point, the default value
     761from ``django.conf.global_settings`` is used.
     762
     763Example::
     764
     765    from django.conf import settings
     766
     767    settings.configure(DEBUG = True, TEMPLATE_DEBUG = True,
     768            TEMPLATE_DIRS = ('/home/web-apps/myapp/',))
     769
     770Following this setup call, if some subsequent calls need, for example, to use
     771the value of ``setings.TEMPLATE_LOADERS``, the default value will be used.
     772
     773If, for some reason, you would like default values to come from somewhere
     774other than ``django.conf.global_settings``, you can pass in a module or class
     775that provides the default settings as the ``default_settings`` argument (or as
     776the first positional argument) in the call to ``configure()``. For example::
     777
     778    from django.conf import settings
     779    from myapp import myapp_defaults
     780
     781    settings.configure(default_settings = myapp_defaults, DEBUG = True)
     782
     783    # Now all defaults will be taken from myapp_defaults and DEBUG will be
     784    # set as requested.
     785    #
     786    # settings.configure(myapp_defaults, DEBUG = True) would also have worked.
     787
  • docs/i18n.txt

     
    540540a big project out of several apps and put all translations into one big project
    541541message file. The choice is yours.
    542542
     543.. note::
     544
     545    If you are using manually configured settings as described in the
     546    `settings`_ documentation, the ``locale`` directory in the project directory
     547    will not be examined, since Django loses the ability to work out where the
     548    project directory is (it normally uses the location of the settings file
     549    to determine this and this file does not exist in the manually configured
     550    case).
     551
     552.. _settings: http://www.djangoproject.com/documentation/settings/#using-settings-without-the-django-settings-module-environment-variable
     553
    543554All message file repositories are structured the same way. They are:
    544555
    545556    * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
  • docs/templates_python.txt

     
    77reference on the language syntax, see
    88`The Django template language: For template authors`_.
    99
     10If you are looking to use the Django template system as part of another
     11application, make sure to read the `configuration`_ section later in this
     12document for how to configure the template system after importing the right
     13pieces.
     14
    1015.. _`The Django template language: For template authors`: http://www.djangoproject.com/documentation/templates/
    1116
    1217Basics
     
    876881For more examples of complex rendering, see the source code for ``{% if %}``,
    877882``{% for %}``, ``{% ifequal %}`` and ``{% ifchanged %}``. They live in
    878883``django/template/defaulttags.py``.
     884
     885.. _configuration:
     886
     887Configuring the template system in standalone mode
     888===================================================
     889
     890.. note::
     891
     892    This section is only of interest to people trying to use the template
     893    system as an output component in another application. If you are using the
     894    template system as part of a Django application, nothing here applies to
     895    you.
     896
     897Normally, Django will load all the configuration information it needs from its
     898own default configuration file, combined with the settings in the module given
     899in the ``DJANGO_SETTINGS_MODULE`` environment variable. When using the
     900template system independently of the rest of Django, the environment variable
     901approach is not very convenient because you probably want to configure the
     902template system in line with the rest of your application.
     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 make. 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``. The full set of available settings are described in the
     912`settings documentation`_ and any settings starting with the word *TEMPLATE_*
     913are 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/
     917
Back to Top