diff options
Diffstat (limited to 'livesettings/models.py')
-rw-r--r-- | livesettings/models.py | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/livesettings/models.py b/livesettings/models.py new file mode 100644 index 00000000..43f14648 --- /dev/null +++ b/livesettings/models.py @@ -0,0 +1,170 @@ +from django.conf import settings +from django.contrib.sites.models import Site +from django.db import models +from django.db.models import loading +from django.utils.translation import ugettext_lazy as _ +from keyedcache import cache_key, cache_get, cache_set, NotCachedError +from keyedcache.models import CachedObjectMixin +from livesettings.overrides import get_overrides +import logging + +log = logging.getLogger('configuration.models') + +__all__ = ['SettingNotSet', 'Setting', 'LongSetting', 'find_setting'] + +def _safe_get_siteid(site): + if not site: + try: + site = Site.objects.get_current() + siteid = site.id + except: + siteid = settings.SITE_ID + else: + siteid = site.id + return siteid + +def find_setting(group, key, site=None): + """Get a setting or longsetting by group and key, cache and return it.""" + + siteid = _safe_get_siteid(site) + setting = None + + use_db, overrides = get_overrides(siteid) + ck = cache_key('Setting', siteid, group, key) + + if use_db: + try: + setting = cache_get(ck) + + except NotCachedError, nce: + if loading.app_cache_ready(): + try: + setting = Setting.objects.get(site__id__exact=siteid, key__exact=key, group__exact=group) + + except Setting.DoesNotExist: + # maybe it is a "long setting" + try: + setting = LongSetting.objects.get(site__id__exact=siteid, key__exact=key, group__exact=group) + + except LongSetting.DoesNotExist: + pass + + cache_set(ck, value=setting) + + else: + grp = overrides.get(group, None) + if grp and grp.has_key(key): + val = grp[key] + setting = ImmutableSetting(key=key, group=group, value=val) + log.debug('Returning overridden: %s', setting) + + if not setting: + raise SettingNotSet(key, cachekey=ck) + + return setting + +class SettingNotSet(Exception): + def __init__(self, k, cachekey=None): + self.key = k + self.cachekey = cachekey + self.args = [self.key, self.cachekey] + +class SettingManager(models.Manager): + def get_query_set(self): + all = super(SettingManager, self).get_query_set() + siteid = _safe_get_siteid(None) + return all.filter(site__id__exact=siteid) + + +class ImmutableSetting(object): + + def __init__(self, group="", key="", value="", site=1): + self.site = site + self.group = group + self.key = key + self.value = value + + def cache_key(self, *args, **kwargs): + return cache_key('OverrideSetting', self.site, self.group, self.key) + + def delete(self): + pass + + def save(self, *args, **kwargs): + pass + + def __repr__(self): + return "ImmutableSetting: %s.%s=%s" % (self.group, self.key, self.value) + + +class Setting(models.Model, CachedObjectMixin): + site = models.ForeignKey(Site, verbose_name=_('Site')) + group = models.CharField(max_length=100, blank=False, null=False) + key = models.CharField(max_length=100, blank=False, null=False) + value = models.CharField(max_length=255, blank=True) + + objects = SettingManager() + + def __nonzero__(self): + return self.id is not None + + def cache_key(self, *args, **kwargs): + return cache_key('Setting', self.site, self.group, self.key) + + def delete(self): + self.cache_delete() + super(Setting, self).delete() + + def save(self, force_insert=False, force_update=False): + try: + site = self.site + except Site.DoesNotExist: + self.site = Site.objects.get_current() + + super(Setting, self).save(force_insert=force_insert, force_update=force_update) + + self.cache_set() + + class Meta: + unique_together = ('site', 'group', 'key') + + +class LongSettingManager(models.Manager): + def get_query_set(self): + all = super(LongSettingManager, self).get_query_set() + siteid = _safe_get_siteid(None) + return all.filter(site__id__exact=siteid) + +class LongSetting(models.Model, CachedObjectMixin): + """A Setting which can handle more than 255 characters""" + site = models.ForeignKey(Site, verbose_name=_('Site')) + group = models.CharField(max_length=100, blank=False, null=False) + key = models.CharField(max_length=100, blank=False, null=False) + value = models.TextField(blank=True) + + objects = LongSettingManager() + + def __nonzero__(self): + return self.id is not None + + def cache_key(self, *args, **kwargs): + # note same cache pattern as Setting. This is so we can look up in one check. + # they can't overlap anyway, so this is moderately safe. At the worst, the + # Setting will override a LongSetting. + return cache_key('Setting', self.site, self.group, self.key) + + def delete(self): + self.cache_delete() + super(LongSetting, self).delete() + + def save(self, force_insert=False, force_update=False): + try: + site = self.site + except Site.DoesNotExist: + self.site = Site.objects.get_current() + super(LongSetting, self).save(force_insert=force_insert, force_update=force_update) + self.cache_set() + + class Meta: + unique_together = ('site', 'group', 'key') + |