diff options
| -rw-r--r-- | ishtar_common/forms.py | 34 | ||||
| -rw-r--r-- | ishtar_common/models.py | 55 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 3 | 
3 files changed, 69 insertions, 23 deletions
| diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 83b0b2b69..8d0d80497 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -26,9 +26,9 @@ import re  import types  from django import forms +from django.apps import apps  from django.conf import settings  from django.contrib.auth.models import User -from django.contrib.contenttypes.models import ContentType  from django.core.exceptions import ValidationError  from django.core.urlresolvers import reverse  from django.core import validators @@ -258,18 +258,8 @@ class CustomForm(BSForm):          if app_name == "archaeological_files_pdl":              app_name = "archaeological_files"          model_name = cls.form_slug.split("-")[0].replace('_', "") -        ct = ContentType.objects.get(app_label=app_name, model=model_name) -        ct_class = ct.model_class() -        choices = set() -        splitted_key = key[len('data__'):].split('__') -        for obj in ct_class.objects.filter( -                data__has_key=key[len('data__'):]).all(): -            value = obj.data -            for k in splitted_key: -                value = value[k] -            choices.add(value) -        choices = [('', '')] + [(v, v) for v in sorted(list(choices))] -        return choices +        ct_class = apps.get_model(app_name, model_name) +        return ct_class._get_dynamic_choices(key)      @classmethod      def _get_json_fields(cls, custom_form): @@ -279,16 +269,18 @@ class CustomForm(BSForm):          :return: ((order1, key1, field1), ...)          """          fields = [] -        for field in custom_form.json_fields.order_by('order').all(): -            key = "data__" + field.json_field.key +        for field in custom_form.json_fields.values( +                "order", "label", "json_field__name", "json_field__value_type", +                "help_text", "json_field__key").order_by('order').all(): +            key = "data__" + field["json_field__key"]              field_cls, widget = forms.CharField, None -            if field.json_field.value_type in JSON_VALUE_TYPES_FIELDS: +            if field["json_field__value_type"] in JSON_VALUE_TYPES_FIELDS:                  field_cls, widget = JSON_VALUE_TYPES_FIELDS[ -                    field.json_field.value_type] -            attrs = {'label': field.label or field.json_field.name, +                    field["json_field__value_type"]] +            attrs = {'label': field["label"] or field["json_field__name"],                       'required': False} -            if field.help_text: -                attrs['help_text'] = field.help_text +            if field["help_text"]: +                attrs['help_text'] = field["help_text"]              if widget:                  attrs['widget'] = widget()              if field_cls == widgets.Select2DynamicField: @@ -299,7 +291,7 @@ class CustomForm(BSForm):                  kls = f.widget.attrs['class'] + " " + kls              f.widget.attrs['class'] = kls              f.alt_name = slugify(attrs['label']) -            fields.append((field.order or 1, key, f)) +            fields.append((field["order"] or 1, key, f))          return fields      @classmethod diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 98998eb1f..96dfa716c 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -447,7 +447,22 @@ class OwnPerms(object):          return q -class Cached(object): +class CachedGen(object): +    @classmethod +    def refresh_cache(cls): +        raise NotImplementedError() + +    @classmethod +    def _add_cache_key_to_refresh(cls, keys): +        cache_ckey, current_keys = get_cache(cls, ['_current_keys']) +        if type(current_keys) != list: +            current_keys = [] +        if keys not in current_keys: +            current_keys.append(keys) +            cache.set(cache_ckey, current_keys, settings.CACHE_TIMEOUT) + + +class Cached(CachedGen):      slug_field = 'txt_idx'      @classmethod @@ -1187,7 +1202,7 @@ class JsonDataField(models.Model):                  _(u"Content types of the field and of the menu do not match")) -class JsonData(models.Model): +class JsonData(models.Model, CachedGen):      data = JSONField(default={}, db_index=True, blank=True)      class Meta: @@ -1233,6 +1248,42 @@ class JsonData(models.Model):              sections[-1][1].append((field.name, value))          return sections +    @classmethod +    def refresh_cache(cls): +        __, refreshed = get_cache(cls, ['cache_refreshed']) +        if refreshed and time.time() - refreshed < 1: +            return +        cache_ckey, current_keys = get_cache(cls, ['_current_keys']) +        if not current_keys: +            return +        for keys in current_keys: +            if keys[0] == '__get_dynamic_choices': +                cls._get_dynamic_choices(keys[1], force=True) + +    @classmethod +    def _get_dynamic_choices(cls, key, force=False): +        """ +        Get choice from existing values +        :param key: data key +        :param force: if set to True do not use cache +        :return: tuple of choices (id, value) +        """ +        cache_key, value = get_cache(cls, ['__get_dynamic_choices', key]) +        if not force and value: +            return value +        choices = set() +        splitted_key = key[len('data__'):].split('__') +        for obj in cls.objects.filter( +                data__has_key=key[len('data__'):]).values("data").all(): +            value = obj['data'] +            for k in splitted_key: +                value = value[k] +            choices.add(value) +        choices = [('', '')] + [(v, v) for v in sorted(list(choices))] +        cache.set(cache_key, choices, settings.CACHE_SMALLTIMEOUT) +        return choices + +  class Imported(models.Model):      imports = models.ManyToManyField( diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 1d44026e0..55e3a3a75 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -309,6 +309,9 @@ def cached_label_changed(sender, **kwargs):      if not force_update and hasattr(instance, '_cached_label_checked') \              and instance._cached_label_checked:          return +    if hasattr(instance, "refresh_cache"): +        instance.refresh_cache() +      instance._cached_label_checked = True      cached_labels = ['cached_label']      if hasattr(sender, 'CACHED_LABELS'): | 
