mirror of
https://github.com/django/django.git
synced 2025-07-19 17:19:12 +00:00
Removed some import-time dependencies on Django's settings.
Now you can import the file storage stuff and still call settings.configure() afterwards. There is still one import-time usage of settings in django.contrib.comments, but that's unavoidable. Backport of r9945 and r9946 from trunk (this is needed in order to fix #8193 in a clean fashion, which is why it's being backported). git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@9947 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
9576353835
commit
32be118081
@ -8,40 +8,19 @@ a list of all possible variables.
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import time # Needed for Windows
|
import time # Needed for Windows
|
||||||
|
|
||||||
from django.conf import global_settings
|
from django.conf import global_settings
|
||||||
|
from django.utils.functional import LazyObject
|
||||||
|
|
||||||
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
||||||
|
|
||||||
class LazySettings(object):
|
class LazySettings(LazyObject):
|
||||||
"""
|
"""
|
||||||
A lazy proxy for either global Django settings or a custom settings object.
|
A lazy proxy for either global Django settings or a custom settings object.
|
||||||
The user can manually configure settings prior to using them. Otherwise,
|
The user can manually configure settings prior to using them. Otherwise,
|
||||||
Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
|
Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def _setup(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':
|
|
||||||
# Assign directly to self.__dict__, because otherwise we'd call
|
|
||||||
# __setattr__(), which would be an infinite loop.
|
|
||||||
self.__dict__['_target'] = value
|
|
||||||
else:
|
|
||||||
if self._target is None:
|
|
||||||
self._import_settings()
|
|
||||||
setattr(self._target, name, value)
|
|
||||||
|
|
||||||
def _import_settings(self):
|
|
||||||
"""
|
"""
|
||||||
Load the settings module pointed to by the environment variable. This
|
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
|
is used the first time we need any settings at all, if the user has not
|
||||||
@ -56,7 +35,7 @@ class LazySettings(object):
|
|||||||
# problems with Python's interactive help.
|
# problems with Python's interactive help.
|
||||||
raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE)
|
raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE)
|
||||||
|
|
||||||
self._target = Settings(settings_module)
|
self._wrapped = Settings(settings_module)
|
||||||
|
|
||||||
def configure(self, default_settings=global_settings, **options):
|
def configure(self, default_settings=global_settings, **options):
|
||||||
"""
|
"""
|
||||||
@ -69,13 +48,13 @@ class LazySettings(object):
|
|||||||
holder = UserSettingsHolder(default_settings)
|
holder = UserSettingsHolder(default_settings)
|
||||||
for name, value in options.items():
|
for name, value in options.items():
|
||||||
setattr(holder, name, value)
|
setattr(holder, name, value)
|
||||||
self._target = holder
|
self._wrapped = holder
|
||||||
|
|
||||||
def configured(self):
|
def configured(self):
|
||||||
"""
|
"""
|
||||||
Returns True if the settings have already been configured.
|
Returns True if the settings have already been configured.
|
||||||
"""
|
"""
|
||||||
return bool(self._target)
|
return bool(self._wrapped)
|
||||||
configured = property(configured)
|
configured = property(configured)
|
||||||
|
|
||||||
class Settings(object):
|
class Settings(object):
|
||||||
|
@ -4,11 +4,12 @@ import urlparse
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
|
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
|
||||||
from django.utils.encoding import force_unicode
|
|
||||||
from django.utils.text import get_valid_filename
|
|
||||||
from django.utils._os import safe_join
|
|
||||||
from django.core.files import locks, File
|
from django.core.files import locks, File
|
||||||
from django.core.files.move import file_move_safe
|
from django.core.files.move import file_move_safe
|
||||||
|
from django.utils.encoding import force_unicode
|
||||||
|
from django.utils.functional import LazyObject
|
||||||
|
from django.utils.text import get_valid_filename
|
||||||
|
from django.utils._os import safe_join
|
||||||
|
|
||||||
__all__ = ('Storage', 'FileSystemStorage', 'DefaultStorage', 'default_storage')
|
__all__ = ('Storage', 'FileSystemStorage', 'DefaultStorage', 'default_storage')
|
||||||
|
|
||||||
@ -116,12 +117,20 @@ class Storage(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
# Needed by django.utils.functional.LazyObject (via DefaultStorage).
|
||||||
|
def get_all_members(self):
|
||||||
|
return self.__members__
|
||||||
|
|
||||||
class FileSystemStorage(Storage):
|
class FileSystemStorage(Storage):
|
||||||
"""
|
"""
|
||||||
Standard filesystem storage
|
Standard filesystem storage
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, location=settings.MEDIA_ROOT, base_url=settings.MEDIA_URL):
|
def __init__(self, location=None, base_url=None):
|
||||||
|
if location is None:
|
||||||
|
location = settings.MEDIA_ROOT
|
||||||
|
if base_url is None:
|
||||||
|
base_url = settings.MEDIA_URL
|
||||||
self.location = os.path.abspath(location)
|
self.location = os.path.abspath(location)
|
||||||
self.base_url = base_url
|
self.base_url = base_url
|
||||||
|
|
||||||
@ -212,7 +221,9 @@ class FileSystemStorage(Storage):
|
|||||||
raise ValueError("This file is not accessible via a URL.")
|
raise ValueError("This file is not accessible via a URL.")
|
||||||
return urlparse.urljoin(self.base_url, name).replace('\\', '/')
|
return urlparse.urljoin(self.base_url, name).replace('\\', '/')
|
||||||
|
|
||||||
def get_storage_class(import_path):
|
def get_storage_class(import_path=None):
|
||||||
|
if import_path is None:
|
||||||
|
import_path = settings.DEFAULT_FILE_STORAGE
|
||||||
try:
|
try:
|
||||||
dot = import_path.rindex('.')
|
dot = import_path.rindex('.')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -227,5 +238,8 @@ def get_storage_class(import_path):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise ImproperlyConfigured('Storage module "%s" does not define a "%s" class.' % (module, classname))
|
raise ImproperlyConfigured('Storage module "%s" does not define a "%s" class.' % (module, classname))
|
||||||
|
|
||||||
DefaultStorage = get_storage_class(settings.DEFAULT_FILE_STORAGE)
|
class DefaultStorage(LazyObject):
|
||||||
|
def _setup(self):
|
||||||
|
self._wrapped = get_storage_class()()
|
||||||
|
|
||||||
default_storage = DefaultStorage()
|
default_storage = DefaultStorage()
|
||||||
|
@ -251,3 +251,39 @@ def allow_lazy(func, *resultclasses):
|
|||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
return lazy(func, *resultclasses)(*args, **kwargs)
|
return lazy(func, *resultclasses)(*args, **kwargs)
|
||||||
return wraps(func)(wrapper)
|
return wraps(func)(wrapper)
|
||||||
|
|
||||||
|
class LazyObject(object):
|
||||||
|
"""
|
||||||
|
A wrapper for another class that can be used to delay instantiation of the
|
||||||
|
wrapped class.
|
||||||
|
|
||||||
|
This is useful, for example, if the wrapped class needs to use Django
|
||||||
|
settings at creation time: we want to permit it to be imported without
|
||||||
|
accessing settings.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self._wrapped = None
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
if self._wrapped is None:
|
||||||
|
self._setup()
|
||||||
|
if name == "__members__":
|
||||||
|
# Used to implement dir(obj)
|
||||||
|
return self._wrapped.get_all_members()
|
||||||
|
return getattr(self._wrapped, name)
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
if name == "_wrapped":
|
||||||
|
# Assign to __dict__ to avoid infinite __setattr__ loops.
|
||||||
|
self.__dict__["_wrapped"] = value
|
||||||
|
else:
|
||||||
|
if self._wrapped is None:
|
||||||
|
self._setup()
|
||||||
|
setattr(self._wrapped, name, value)
|
||||||
|
|
||||||
|
def _setup(self):
|
||||||
|
"""
|
||||||
|
Must be implemented by subclasses to initialise the wrapped object.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user