diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/migrations/0201_squashed.py | 6 | ||||
| -rw-r--r-- | ishtar_common/models.py | 1 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 91 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 98 | 
4 files changed, 115 insertions, 81 deletions
| diff --git a/ishtar_common/migrations/0201_squashed.py b/ishtar_common/migrations/0201_squashed.py index 08912e1ee..aa5582f9a 100644 --- a/ishtar_common/migrations/0201_squashed.py +++ b/ishtar_common/migrations/0201_squashed.py @@ -207,7 +207,7 @@ class Migration(migrations.Migration):                     ishtar_common.models.OwnPerms, models.Model,                     ishtar_common.models.CachedGen,                     ishtar_common.models_common.FixAssociated, -                   ishtar_common.models.CascasdeUpdate, ishtar_common.models.ImageContainerModel, ishtar_common.models.ValueGetter, ishtar_common.models.MainItem), +                   ishtar_common.models.ImageContainerModel, ishtar_common.models.ValueGetter, ishtar_common.models.MainItem),          ),          migrations.CreateModel(              name='DocumentTemplate', @@ -755,7 +755,7 @@ class Migration(migrations.Migration):                     ishtar_common.models.TemplateItem, models.Model,                     ishtar_common.models.CachedGen,                     ishtar_common.models_common.FixAssociated, -                   ishtar_common.models.CascasdeUpdate, ishtar_common.models.OwnPerms, ishtar_common.models.ValueGetter, ishtar_common.models.MainItem), +                   ishtar_common.models.OwnPerms, ishtar_common.models.ValueGetter, ishtar_common.models.MainItem),          ),          migrations.CreateModel(              name='OrganizationType', @@ -831,7 +831,7 @@ class Migration(migrations.Migration):                     ishtar_common.models.TemplateItem, models.Model,                     ishtar_common.models.CachedGen,                     ishtar_common.models_common.FixAssociated, -                   ishtar_common.models.CascasdeUpdate, ishtar_common.models.OwnPerms, ishtar_common.models.ValueGetter, ishtar_common.models.MainItem), +                   ishtar_common.models.OwnPerms, ishtar_common.models.ValueGetter, ishtar_common.models.MainItem),          ),          migrations.CreateModel(              name='PersonType', diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 420670ca1..c053f7c10 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -164,7 +164,6 @@ from ishtar_common.models_common import (      ImageContainerModel,      StatisticItem,      CachedGen, -    CascasdeUpdate,      Department,      State,  ) diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 5a27f8ca9..fd12f19be 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -69,6 +69,7 @@ from ishtar_common.utils import (      get_all_field_names,      merge_tsvectors,      cached_label_changed, +    external_id_changed,      post_save_geo,      post_save_geodata,      task, @@ -1188,7 +1189,7 @@ class JsonData(models.Model, CachedGen):                      else:                          print("To many level in json field - fix not managed")                      obj.data = data -                    obj._no_post_process = True +                    obj.no_post_process()                      obj.save()                  multi = True                  for v in value: @@ -1248,22 +1249,6 @@ class FixAssociated:                      setattr(item, subkey, new_value) -class CascasdeUpdate: -    DOWN_MODEL_UPDATE = [] - -    def cascade_update(self): -        for down_model in self.DOWN_MODEL_UPDATE: -            if not settings.USE_BACKGROUND_TASK: -                rel = getattr(self, down_model) -                if hasattr(rel.model, "need_update"): -                    rel.update(need_update=True) -                    continue -            for item in getattr(self, down_model).all(): -                cached_label_changed(item.__class__, instance=item) -                if hasattr(item, "main_geodata"): -                    post_save_geo(item.__class__, instance=item) - -  class SearchAltName(object):      def __init__(          self, search_key, search_query, extra_query=None, distinct_query=False @@ -1436,7 +1421,6 @@ class BaseHistorizedItem(      Imported,      JsonData,      FixAssociated, -    CascasdeUpdate,  ):      """      Historized item with external ID management. @@ -1731,12 +1715,6 @@ class BaseHistorizedItem(      def save(self, *args, **kwargs):          created = not self.pk -        if getattr(self, "_no_post_process", False): -            self.skip_history_when_saving = True -            self._cached_label_checked = True -            self._post_saved_geo = True -            self._no_move = True -          if (not getattr(self, "skip_history_when_saving", False)              and not getattr(self, "_no_last_modified_update", False)) \                  or not self.last_modified: @@ -4176,7 +4154,7 @@ class CompleteIdentifierItem(models.Model, ImageContainerModel):          super(CompleteIdentifierItem, self).save(*args, **kwargs)          self.regenerate_all_ids() -    def regenerate_all_ids(self): +    def regenerate_all_ids(self, save=True):          if getattr(self, "_prevent_loop", False):              return          modified = False @@ -4191,7 +4169,9 @@ class CompleteIdentifierItem(models.Model, ImageContainerModel):          if modified:              self._prevent_loop = True              self.skip_history_when_saving = True -            self.save() +            if save: +                self.save() +        return modified  class SearchVectorConfig: @@ -4383,10 +4363,54 @@ class MainItem(ShortMenuItem, SerializeItem):      """      Item with quick actions available from tables      Extra actions are available from sheets +    Manage cascade updated, has_changed and no_post_process      """      QUICK_ACTIONS = []      SLUG = "" +    DOWN_MODEL_UPDATE = [] +    INITIAL_VALUES = []  # list of field checkable if changed on save + +    def __init__(self, *args, **kwargs): +        super().__init__(*args, **kwargs) +        self._initial_values = {} +        for field_name in self.INITIAL_VALUES: +            self._initial_values[field_name] = getattr(self, field_name) + +    def has_changed(self): +        """ +        Check which field have a changed value between INITIAL_VALUES +        :return: list of changed fields +        """ +        changed = [] +        for field_name in self._initial_values: +            value = getattr(self, field_name) +            if self._initial_values[field_name] != value: +                changed.append(field_name) +                self._initial_values[field_name] = value +        return changed + +    def cascade_update(self, changed=True): +        if not changed: +            return +        for down_model in self.DOWN_MODEL_UPDATE: +            if not settings.USE_BACKGROUND_TASK: +                rel = getattr(self, down_model) +                if hasattr(rel.model, "need_update"): +                    rel.update(need_update=True) +                    continue +            for item in getattr(self, down_model).all(): +                item.cached_label_changed() +                if hasattr(item, "main_geodata"): +                    item.post_save_geo() + +    def no_post_process(self): +        self.skip_history_when_saving = True +        self._cached_label_checked = True +        self._post_saved_geo = True +        self._external_id_changed = False +        self._search_updated = True +        self._no_move = True      @classmethod      def app_label(cls): @@ -4450,6 +4474,21 @@ class MainItem(ShortMenuItem, SerializeItem):          self.auto_external_id = True          self.save() +    def cached_label_changed(self): +        self.no_post_process() +        self._cached_label_checked = False +        cached_label_changed(self.__class__, instance=self, created=False) + +    def post_save_geo(self): +        self.no_post_process() +        self._post_saved_geo = False +        post_save_geo(self.__class__, instance=self, created=False) + +    def external_id_changed(self): +        self.no_post_process() +        self._external_id_changed = False +        external_id_changed(self.__class__, instance=self, created=False) +      def get_extra_actions(self, request):          if not hasattr(self, "SLUG"):              return [] diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 7c7e6a6a5..65b937339 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -503,41 +503,42 @@ def revoke_old_task(kwargs, action_name, task_id, instance_cls):      cache.set(key, task_id, settings.CACHE_TIMEOUT * 4) -def cached_label_changed(sender, **kwargs): -    if not kwargs.get("instance"): +def load_task(task_func, task_name, checks, sender, **kwargs): +    instance = kwargs.get("instance", None) +    if not instance:          return -    instance = kwargs.get("instance")      if hasattr(instance, "test_obj"):          instance.test_obj.reached(sender, **kwargs) -    # cache_key, value = get_cache( -    #     sender, ["cached_label_changed", kwargs['instance'].pk] -    # ) -    # if value and not settings.DISABLE_TASK_TIMEOUT: -    #     # multiple request too quick -    #     return -    # cache.set(cache_key, True, settings.CACHE_TASK_TIMEOUT) +    if checks: +        for check in checks: +            if getattr(instance, check, None): +                return      if ( -        not settings.USE_BACKGROUND_TASK -        or not instance.pk -        or not sender.objects.filter(pk=instance.pk).count() +            not settings.USE_BACKGROUND_TASK +            or not instance.pk +            or not sender.objects.filter(pk=instance.pk).count()      ):          # no background task or not yet fully saved -        return _cached_label_changed(sender, **kwargs) - +        return task_func(sender, **kwargs)      if getattr(instance, "_cascade_change", False):          kwargs["cascade_change"] = True      sender, kwargs = serialize_args_for_tasks(          sender, instance, kwargs, EXTRA_KWARGS_TRIGGER      ) -    task_item = _cached_label_changed.delay(sender, **kwargs) -    revoke_old_task(kwargs, "cached_label_changed", task_item.id, instance.__class__) +    task_item = task_func.delay(sender, **kwargs) +    revoke_old_task(kwargs, task_name, task_item.id, instance.__class__)      return task_item +def cached_label_changed(sender, **kwargs): +    return load_task(_cached_label_changed, "cached_label_changed", None, sender, +                     **kwargs) + +  @task()  def _cached_label_changed(sender, **kwargs):      sender, instance = deserialize_args_for_tasks(sender, kwargs, EXTRA_KWARGS_TRIGGER) @@ -613,6 +614,30 @@ def regenerate_all_cached_labels(model):          cached_label_changed(model, instance=item) +def external_id_changed(sender, **kwargs): +    return load_task(_external_id_changed, "external_id_changed", +                     ["_external_id_changed"], sender, **kwargs) + + +@task() +def _external_id_changed(sender, **kwargs): +    sender, instance = deserialize_args_for_tasks(sender, kwargs, EXTRA_KWARGS_TRIGGER) +    if not instance: +        return +    updated = False +    instance.no_post_process() +    if not instance.external_id or instance.auto_external_id: +        external_id = get_generated_id(instance.SLUG + "_external_id", instance) +        if external_id != instance.external_id: +            updated = True +            instance.auto_external_id = True +            instance.external_id = external_id +    updated |= instance.regenerate_all_ids(save=False) +    if updated: +        instance.save() + + +  def shortify(lbl, number=20):      SHORTIFY_STR = ugettext(" (...)")      if not lbl: @@ -749,19 +774,8 @@ def get_srid_obj_from_point(point):  def post_save_geodata(sender, **kwargs): -    instance = kwargs.get("instance", None) -    if not instance: -        return -    if hasattr(instance, "_no_geo_check") and instance._no_geo_check: -        return -    if not settings.USE_BACKGROUND_TASK: -        return _post_save_geodata(sender, **kwargs) -    sender, kwargs = serialize_args_for_tasks( -        sender, instance, kwargs, EXTRA_KWARGS_TRIGGER -    ) -    task_item = _post_save_geodata.delay(sender, **kwargs) -    revoke_old_task(kwargs, "post_save_geodata", task_item.id, instance.__class__) -    return task_item +    return load_task(_post_save_geodata, "post_save_geodata", ["_no_geo_check"], sender, +                     **kwargs)  @task() @@ -817,26 +831,8 @@ def post_save_geo(sender, **kwargs):      """      Convert raw x, y, z point to real geo field      """ -    if not kwargs.get("instance"): -        return -    # cache_key, value = get_cache( -    #     sender, ["post_save_geo", kwargs['instance'].pk]) -    # if value and not settings.DISABLE_TASK_TIMEOUT: -    #     # multiple request too quick -    #     return -    # cache.set(cache_key, True, settings.CACHE_TASK_TIMEOUT) - -    instance = kwargs.get("instance") -    if hasattr(instance, "_no_geo_check") and instance._no_geo_check: -        return -    if not settings.USE_BACKGROUND_TASK: -        return _post_save_geo(sender, **kwargs) -    sender, kwargs = serialize_args_for_tasks( -        sender, instance, kwargs, EXTRA_KWARGS_TRIGGER -    ) -    task_item = _post_save_geo.delay(sender, **kwargs) -    revoke_old_task(kwargs, "post_save_geo", task_item.id, instance.__class__) -    return task_item +    return load_task(_post_save_geo, "post_save_geo", ["_no_geo_check"], +                     sender, **kwargs)  @task() @@ -1966,7 +1962,7 @@ def get_generated_id(key, item):      profile = get_current_profile()      if not hasattr(profile, key):          return -    formula = getattr(profile, key) +    formula = getattr(profile, key, None)      if not formula:          return "" | 
