summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2019-03-20 11:16:50 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2019-03-20 11:16:50 +0100
commit0ea89f12deae7c59b0f5901662c6a519a8f1e017 (patch)
tree348545788363e80b70d18856d28182242b82e9aa /ishtar_common
parentac80884a42b5fd6032dff409346387616287abd5 (diff)
downloadIshtar-0ea89f12deae7c59b0f5901662c6a519a8f1e017.tar.bz2
Ishtar-0ea89f12deae7c59b0f5901662c6a519a8f1e017.zip
Cache dynamic choices
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/forms.py34
-rw-r--r--ishtar_common/models.py55
-rw-r--r--ishtar_common/utils.py3
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'):