Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Django settings.py that can handle
"""Multisite - individual site for request"""
from django.conf import settings
from threading import local
def make_tls_property(default=None):
"""Creates a class-wide instance property with a thread-specific value."""
class TLSProperty(object):
def __init__(self):
self.local = local()
def __get__(self, instance, cls):
if not instance:
return self
return self.value
def __set__(self, instance, value):
# TODO: This is not called on any of the tests -- is this useless?
self.value = value
def _get_value(self):
return getattr(self.local, 'value', default)
def _set_value(self, value):
self.local.value = value
value = property(_get_value, _set_value)
return TLSProperty()
def _patch_setattr(obj):
"""Purpose of this is to allow changes to settings object again after it is
changed to tls property.
Without this patch the following is not possible::
settings.SITE_ID = 1
settings.SITE_ID = 42
assert settings.SITE_ID == 42 # this fails without this patch
"""
old_setattr = obj.__setattr__
def wrap_setattr(self, name, value):
try:
getattr(self.__class__, name).value = value
except AttributeError:
old_setattr(name, value)
obj.__class__.__setattr__ = wrap_setattr
_patch_setattr(settings)
DEFAULT_SITE_ID = getattr(settings, 'SITE_ID', None)
DEFAULT_MEDIA_URL = getattr(settings, 'MEDIA_URL', None)
DEFAULT_MEDIA_ROOT = getattr(settings, 'MEDIA_ROOT', None)
DEFAULT_MEDIA = getattr(settings, 'MEDIA', None)
settings.__class__.SITE_ID = make_tls_property(DEFAULT_SITE_ID)
settings.__class__.MEDIA_URL = make_tls_property(DEFAULT_MEDIA_URL)
settings.__class__.MEDIA_ROOT = make_tls_property(DEFAULT_MEDIA_ROOT)
settings.__class__.MEDIA = make_tls_property(DEFAULT_MEDIA)
settings.__class__.REQUEST = make_tls_property()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment