diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-06-07 15:07:45 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-06-07 15:45:30 +0200 |
commit | fac19ea38fbd46bf6d6636e9d12b555269788019 (patch) | |
tree | 3a54cd8f775eeb87ff4a0a2641b7eaa7d89694d6 | |
parent | d3eb2d6fd52e393a7d3d841d66ecdf58b7a94b6a (diff) | |
download | Ishtar-fac19ea38fbd46bf6d6636e9d12b555269788019.tar.bz2 Ishtar-fac19ea38fbd46bf6d6636e9d12b555269788019.zip |
⚡️ improve post treatments after imports
- check_cascade_update is now function which evaluate if cascade update
is relevant
- "_no_repost_save" attribute prevent a resave after post import
- fix updat check for geo post save
- add some logging
-rw-r--r-- | archaeological_context_records/models.py | 1 | ||||
-rw-r--r-- | archaeological_operations/models.py | 1 | ||||
-rw-r--r-- | archaeological_warehouse/models.py | 52 | ||||
-rw-r--r-- | changelog/en/changelog_2022-06-15.md | 7 | ||||
-rw-r--r-- | changelog/fr/changelog_2023-01-25.md | 7 | ||||
-rw-r--r-- | example_project/settings.py | 15 | ||||
-rw-r--r-- | ishtar_common/data_importer.py | 5 | ||||
-rw-r--r-- | ishtar_common/models_common.py | 1 | ||||
-rw-r--r-- | ishtar_common/utils.py | 19 |
9 files changed, 94 insertions, 14 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 8fd0a5ade..21640920e 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -468,6 +468,7 @@ class GeographicSubTownItem(GeoItem): update_fields=False, raw=False, using="default") else: return True + return False class ContextRecord( diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 57fc4676f..9155ce3eb 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -276,6 +276,7 @@ class GeographicTownItem(GeoItem): if changed and save: post_save_geo(self.__class__, instance=self, created=False, update_fields=False, raw=False, using="default") + return changed class ArchaeologicalSite( diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 048f02d4d..392082ba9 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -19,6 +19,7 @@ from collections import OrderedDict import datetime +import logging import uuid from django.conf import settings @@ -62,6 +63,8 @@ from ishtar_common.utils import ( get_generated_id, ) +logger = logging.getLogger(__name__) + class DivisionContainer(DashboardFormItem): DIVISION_TEMPLATE = """<a class="display_details" @@ -323,7 +326,6 @@ class Warehouse( ), } GEO_LABEL = "name" - FORCE_CASCADE_UPDATE = True CACHED_LABELS = ["cached_town_label"] QA_EDIT = QuickAction( @@ -465,6 +467,7 @@ class Warehouse( self.skip_history_when_saving = True self._no_move = True self.save() + return changed def get_container_type_by_place(self, place: int): """ @@ -659,6 +662,19 @@ class Warehouse( return self.town return "" + def check_cascade_update(self): + # arbitrary check if a "location" or a "responsibility" container are impacted by a change + # arbitrary because check every formula is not efficient + q1 = Container.objects.filter(location=self) + q2 = Container.objects.exclude(location=self).filter(responsibility=self) + for q in (q1, q2): + if q.count(): + container = q.all()[0] + if (container._generate_cached_label() != container.cached_label) or ( + container._generate_cached_location() != container.cached_location): + return True + return False + def save(self, *args, **kwargs): self.update_search_vector() super(Warehouse, self).save(*args, **kwargs) @@ -1243,6 +1259,7 @@ class Container( self.skip_history_when_saving = True self._no_move = True self.save() + return changed @property def start_division_number(self): @@ -1328,6 +1345,19 @@ class Container( def _generate_cached_weight(self): return self.weight if self.weight else self.calculated_weight + def update_weight(self) -> bool: + """ + Update weight in db if changed. + :return: True if changed + """ + if not self.pk: + return False + if self.calculated_weight != self._calculate_weight(): + Container.objects.filter(pk=self.pk).update(calculated_weight=self.calculated_weight) + return True + return False + + def _calculate_weight(self) -> bool: """ Calculate the weight of the contained finds + tare weight of the @@ -1669,108 +1699,126 @@ class Container( return self.set_localisation(0, value) set_localisation_1.post_save = True + set_localisation_1._no_repost_save = True @post_importer_action def set_localisation_2(self, context, value): return self.set_localisation(1, value) set_localisation_2.post_save = True + set_localisation_2._no_repost_save = True @post_importer_action def set_localisation_3(self, context, value): return self.set_localisation(2, value) set_localisation_3.post_save = True + set_localisation_3._no_repost_save = True @post_importer_action def set_localisation_4(self, context, value): return self.set_localisation(3, value) set_localisation_4.post_save = True + set_localisation_4._no_repost_save = True @post_importer_action def set_localisation_5(self, context, value): return self.set_localisation(4, value) set_localisation_5.post_save = True + set_localisation_5._no_repost_save = True @post_importer_action def set_localisation_6(self, context, value): return self.set_localisation(5, value) set_localisation_6.post_save = True + set_localisation_6._no_repost_save = True @post_importer_action def set_localisation_7(self, context, value): return self.set_localisation(6, value) set_localisation_7.post_save = True + set_localisation_7._no_repost_save = True @post_importer_action def set_localisation_8(self, context, value): return self.set_localisation(7, value) set_localisation_8.post_save = True + set_localisation_8._no_repost_save = True @post_importer_action def set_localisation_9(self, context, value): return self.set_localisation(8, value) set_localisation_9.post_save = True + set_localisation_9._no_repost_save = True @post_importer_action def set_static_localisation_1(self, context, value): return self.set_static_localisation(0, value) set_static_localisation_1.post_save = True + set_static_localisation_1._no_repost_save = True @post_importer_action def set_static_localisation_2(self, context, value): return self.set_static_localisation(1, value) set_static_localisation_2.post_save = True + set_static_localisation_2._no_repost_save = True @post_importer_action def set_static_localisation_3(self, context, value): return self.set_static_localisation(2, value) set_static_localisation_3.post_save = True + set_static_localisation_3._no_repost_save = True @post_importer_action def set_static_localisation_4(self, context, value): return self.set_static_localisation(3, value) set_static_localisation_4.post_save = True + set_static_localisation_4._no_repost_save = True @post_importer_action def set_static_localisation_5(self, context, value): return self.set_static_localisation(4, value) set_static_localisation_5.post_save = True + set_static_localisation_5._no_repost_save = True @post_importer_action def set_static_localisation_6(self, context, value): return self.set_static_localisation(5, value) set_static_localisation_6.post_save = True + set_static_localisation_6._no_repost_save = True @post_importer_action def set_static_localisation_7(self, context, value): return self.set_static_localisation(6, value) set_static_localisation_7.post_save = True + set_static_localisation_7._no_repost_save = True @post_importer_action def set_static_localisation_8(self, context, value): return self.set_static_localisation(7, value) set_static_localisation_8.post_save = True + set_static_localisation_8._no_repost_save = True @post_importer_action def set_static_localisation_9(self, context, value): return self.set_static_localisation(8, value) set_static_localisation_9.post_save = True + set_static_localisation_9._no_repost_save = True DOC_VALUES = [ ( @@ -1930,6 +1978,8 @@ class Container( return ((self.__class__, q.values_list("id", flat=True)),) def save(self, *args, **kwargs): + if self.pk: + logger.debug(f"[ishtar] archaeological_warehouse.models.Container.save - {self.pk} - {self.cached_label}") self.pre_save() super().save(*args, **kwargs) self._change_child_location(self) diff --git a/changelog/en/changelog_2022-06-15.md b/changelog/en/changelog_2022-06-15.md index 5cf8a58ea..af21a7dd3 100644 --- a/changelog/en/changelog_2022-06-15.md +++ b/changelog/en/changelog_2022-06-15.md @@ -1,3 +1,10 @@ +v4.0.47 - 2023- +-------------------- + +### Technical ### +- Improve post treatments after imports + + v4.0.46 - 2023-05-26 -------------------- diff --git a/changelog/fr/changelog_2023-01-25.md b/changelog/fr/changelog_2023-01-25.md index a8bc98ba8..8dbcafede 100644 --- a/changelog/fr/changelog_2023-01-25.md +++ b/changelog/fr/changelog_2023-01-25.md @@ -1,3 +1,10 @@ +v4.0.47 - 2023- +-------------------- + +### Technique ### +- amélioration des post-traitements après import + + v4.0.46 - 2023-05-26 -------------------- diff --git a/example_project/settings.py b/example_project/settings.py index d6bc19bcd..95abc793e 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -204,7 +204,8 @@ AXES_RESET_ON_SUCCESS = True MAIN_APP = "" -LOGFILE = "" +LOG_FILE = "" +LOG_LEVEL = "" default_handler = {"handlers": ["logfile"], "level": "INFO", "propogate": False} @@ -378,8 +379,8 @@ TESTING = sys.argv[1:2] == ["test"] PROJECT_SLUG = locals().get("PROJECT_SLUG", "default") -if LOGFILE: - LOGGING["handlers"]["logfile"]["filename"] = LOGFILE +if LOG_FILE: + LOGGING["handlers"]["logfile"]["filename"] = LOG_FILE elif DEBUG: LOGGING["handlers"]["logfile"]["filename"] = ( ROOT_PATH + "log-" + PROJECT_SLUG + ".log" @@ -394,7 +395,7 @@ INTERNAL_IPS = ("127.0.0.1",) JQUERY_URL = STATIC_URL + "js/jquery.min.js" JQUERY_UI_URL = STATIC_URL + "js/jquery-ui/" -if DEBUG: +if DEBUG and not LOG_FILE: # make all loggers use the console for logger in LOGGING["loggers"]: if DEBUG_TO_CONSOLE: @@ -402,6 +403,12 @@ if DEBUG: elif "console" not in LOGGING["loggers"][logger]["handlers"]: LOGGING["loggers"][logger]["handlers"] += ["console"] +if LOG_LEVEL: + for logger in LOGGING["loggers"]: + LOGGING["loggers"][logger]["level"] = LOG_LEVEL + if logger.startswith("archaeological") or logger.startswith("ishtar"): + LOGGING["loggers"][logger]["level"] = LOG_LEVEL + if USE_BACKGROUND_TASK: if not CELERY_BROKER_URL: CELERY_BROKER_URL = "amqp://localhost" diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py index 796a75699..673bcdde7 100644 --- a/ishtar_common/data_importer.py +++ b/ishtar_common/data_importer.py @@ -1048,8 +1048,9 @@ class Importer(object): for func, context, value in self._item_post_processing: context["import_object"] = self.import_instance try: - returned = getattr(item, func)(context, value) - if returned: + f = getattr(item, func) + returned = f(context, value) + if returned and not getattr(f, "_no_repost_save", False): if not isinstance(returned, Iterable): returned = [returned] for rel in returned: diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 15ce429d4..a8e377209 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -3386,6 +3386,7 @@ class MainItem(ShortMenuItem, SerializeItem): self.no_post_process() self._post_saved_geo = False post_save_geo(self.__class__, instance=self, created=False) + return False def external_id_changed(self): self.no_post_process() diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 1757612ef..c6c14422c 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -23,6 +23,7 @@ import datetime from functools import wraps from itertools import chain from inspect import currentframe, getframeinfo +import logging import hashlib from importlib import import_module import io @@ -85,6 +86,7 @@ else: ) _ = ugettext_lazy +logger = logging.getLogger(__name__) def dict_to_tuple(dct): @@ -559,6 +561,7 @@ def _cached_label_changed(sender, **kwargs): if not force_update and getattr(instance, "_cached_label_checked", False): return + logger.debug(f"[ishtar] ishtar_common.utils._cached_label_changed - {instance.__class__.__name__} - {instance.pk} - {instance}") if hasattr(instance, "refresh_cache"): instance.refresh_cache() @@ -587,8 +590,8 @@ def _cached_label_changed(sender, **kwargs): if hasattr(instance, "_cascade_change") and instance._cascade_change: instance.skip_history_when_saving = True instance.__class__.objects.filter(pk=instance.pk).update(**dict(changed)) - if (getattr(instance, "FORCE_CASCADE_UPDATE", False) or changed - or not cached_labels) and hasattr(instance, "cascade_update"): + if ((getattr(instance, "check_cascade_update", False) and instance.check_cascade_update()) + or changed or not cached_labels) and hasattr(instance, "cascade_update"): instance.cascade_update() updated = False if force_update or hasattr(instance, "update_search_vector"): @@ -603,6 +606,7 @@ def _cached_label_changed(sender, **kwargs): if hasattr(instance, "test_obj"): item.test_obj = instance.test_obj cached_label_changed(item.__class__, instance=item) + cache_key, __ = get_cache(sender, ["cached_label_changed", instance.pk]) cache.set(cache_key, None, settings.CACHE_TASK_TIMEOUT) if cached_labels: @@ -800,9 +804,10 @@ def _post_save_geodata(sender, **kwargs): modified = False if getattr(instance, "post_save_geo", False): - instance.post_save_geo(save=False) - modified = True + # TODO: geovectordata -> no post_save_geo: delete? + modified = instance.post_save_geo(save=False) + logger.debug(f"[ishtar] ishtar_common.utils._post_save_geodata - {instance.__class__.__name__} - {instance.pk} - {instance}") # managed cached coordinates cached_x, cached_y, cached_z = None, None, None @@ -830,7 +835,7 @@ def _post_save_geodata(sender, **kwargs): instance._no_move = True instance.skip_history_when_saving = True instance.save() - cache_key, __ = get_cache(sender, ("post_save_geo", instance.pk)) + cache_key, __ = get_cache(sender, ("post_save_geodata", instance.pk)) cache.set(cache_key, None, settings.CACHE_TASK_TIMEOUT) return @@ -858,12 +863,12 @@ def _post_save_geo(sender, **kwargs): if getattr(instance, "_post_saved_geo", False): return + logger.debug(f"[ishtar] ishtar_common.utils._post_save_geo - {instance.__class__.__name__} - {instance.pk} - {instance}") instance._post_saved_geo = True modified = False if getattr(instance, "post_save_geo", False): - instance.post_save_geo(save=False) - modified = True + modified = instance.post_save_geo(save=False) if hasattr(instance, "need_update") and instance.need_update: instance.need_update = False |