From 3f1de491d60943b8d8f82088febe2af89a8801de Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Tue, 8 Aug 2023 12:20:07 +0200 Subject: ⚡️ optimise post-treatments: prevent unnecessary cascade update (refs #5617) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- archaeological_context_records/models.py | 33 +++++++++++---------- archaeological_warehouse/models.py | 2 +- changelog/en/changelog_2022-06-15.md | 4 ++- changelog/fr/changelog_2023-01-25.md | 4 ++- ishtar_common/models_common.py | 3 ++ ishtar_common/utils.py | 50 ++++++++++++++++++++++++++++++-- 6 files changed, 74 insertions(+), 22 deletions(-) diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 21640920e..f464275bf 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -422,12 +422,10 @@ class GeographicSubTownItem(GeoItem): has_geo_town = ( town and town.main_geodata and town.main_geodata.multi_polygon ) - if has_geo_town: - bad_towns = q_geodata_current_town - elif town: + + bad_towns = q_geodata_current_town + if town: bad_towns = q_geodata_current_town.exclude(source_id=town.id) - else: - return modified = False for bad_town in bad_towns.all(): @@ -446,15 +444,18 @@ class GeographicSubTownItem(GeoItem): if not self.main_geodata: self.main_geodata = upper.main_geodata + if modified and save: + if settings.USE_BACKGROUND_TASK and hasattr(self, "no_post_process"): + self.no_post_process() + else: + self.skip_history_when_saving = True + self._no_move = True + self._post_saved_geo = False + self._no_down_model_update = False + self.save() + if not has_geo_town: - if modified: - if save: - self.skip_history_when_saving = True - self._no_move = True - self.save() - else: - return True - return + return modified if not q_geodata_current_town.filter(source_id=town.id).count(): try: @@ -463,12 +464,12 @@ class GeographicSubTownItem(GeoItem): self.geodata.add(town.main_geodata) except (OperationalError, IntegrityError): pass + if not modified: + return False if save: post_save_geo(self.__class__, instance=self, created=False, update_fields=False, raw=False, using="default") - else: - return True - return False + return True class ContextRecord( diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 392082ba9..82b1e7e4b 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -1357,7 +1357,6 @@ class Container( return True return False - def _calculate_weight(self) -> bool: """ Calculate the weight of the contained finds + tare weight of the @@ -1970,6 +1969,7 @@ class Container( parent = Container.objects.filter(pk=parent).values_list("parent_id")[0][0] if number > self.location.max_division_number: self.location.max_division_number = number + self.location.no_post_process() self.location.save() def post_delete_to_update(self): diff --git a/changelog/en/changelog_2022-06-15.md b/changelog/en/changelog_2022-06-15.md index fc8efbcc3..0c79a4bf8 100644 --- a/changelog/en/changelog_2022-06-15.md +++ b/changelog/en/changelog_2022-06-15.md @@ -3,7 +3,9 @@ v4.0.55 - 2099-12-31 ### Technical ### - `ishtar_maintenance` script: add "filter" option in order to limit script to a specific query -- fix crash with no search counted +- fix crash with no search counted +- fix cascade update for base finds +- optimise post-treatments: prevent unnecessary cascade update (refs #5617) v4.0.54 - 2023-07-19 -------------------- diff --git a/changelog/fr/changelog_2023-01-25.md b/changelog/fr/changelog_2023-01-25.md index 7dad66905..68e4b9777 100644 --- a/changelog/fr/changelog_2023-01-25.md +++ b/changelog/fr/changelog_2023-01-25.md @@ -3,7 +3,9 @@ v4.0.55 - 2099-12-31 ### Technique ### - script `ishtar_maintenance` : ajout de l'option "filter" afin de limiter le script à une requête spécifique -- correction de crash quand aucune recherche n'est comptabilisée +- correction de crash quand aucune recherche n'est comptabilisée +- correction de crash lors de mise à jour en cascade du mobilier d'origine +- optimisation des post-traitements : éviter des mises à jour en cascade inutiles (refs #5617) v4.0.54 - 2023-07-19 -------------------- diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 84b46d2c6..c5c550b5a 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -3319,6 +3319,8 @@ class MainItem(ShortMenuItem, SerializeItem): def cascade_update(self, changed=True): if not changed: return + if getattr(self, "_no_down_model_update", False): + return for down_model in self.DOWN_MODEL_UPDATE: if not settings.USE_BACKGROUND_TASK: rel = getattr(self, down_model) @@ -3338,6 +3340,7 @@ class MainItem(ShortMenuItem, SerializeItem): self._external_id_checked = True self._search_updated = True self._no_move = True + self._no_down_model_update = True @classmethod def app_label(cls): diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 2becd20ce..bbefd085e 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -544,7 +544,26 @@ def load_task(task_func, task_name, checks, sender, **kwargs): def cached_label_changed(sender, **kwargs): - load_task(_external_id_changed, "external_id_changed", None, sender, **kwargs) + if "instance" not in kwargs: + return + instance = kwargs["instance"] + if not instance: + return + if hasattr(instance, "external_id") and hasattr(instance, "auto_external_id") \ + and hasattr(instance, "SLUG") and not getattr(instance, "_external_id_checked", None): + changed = load_task(_external_id_changed, "external_id_changed", None, sender, **kwargs) + if changed and ( + not settings.USE_BACKGROUND_TASK + or not instance.pk + or not sender.objects.filter(pk=instance.pk).count() + ): # cached_label_changed re-triggered + return + + force_update = kwargs.get("force_update", False) + if getattr(instance, "need_update", False): + force_update = True + if not force_update and getattr(instance, "_cached_label_checked", False): + return return load_task(_cached_label_changed, "cached_label_changed", None, sender, **kwargs) @@ -627,6 +646,15 @@ def regenerate_all_cached_labels(model): def external_id_changed(sender, **kwargs): + if "instance" not in kwargs: + return + instance = kwargs["instance"] + if not instance or not hasattr(instance, "external_id") \ + or not hasattr(instance, "auto_external_id") \ + or not hasattr(instance, "SLUG"): + return + if getattr(instance, "_external_id_checked", None): + return return load_task(_external_id_changed, "external_id_changed", ["_external_id_changed"], sender, **kwargs) @@ -651,7 +679,13 @@ def _external_id_changed(sender, **kwargs): updated |= instance.regenerate_all_ids(save=False) or False instance._external_id_checked = True if updated: + if settings.USE_BACKGROUND_TASK and hasattr(instance, "no_post_process"): + instance.no_post_process() + else: + instance._no_move = True + instance.skip_history_when_saving = True instance.save() + return True def shortify(lbl, number=20): @@ -849,6 +883,13 @@ def post_save_geo(sender, **kwargs): """ Convert raw x, y, z point to real geo field """ + if "instance" not in kwargs: + return + instance = kwargs["instance"] + if not instance: + return + if getattr(instance, "_post_saved_geo", False): + return return load_task(_post_save_geo, "post_save_geo", ["_no_geo_check"], sender, **kwargs) @@ -880,8 +921,11 @@ def _post_save_geo(sender, **kwargs): modified = True if modified: - instance.skip_history_when_saving = True - instance._post_saved_geo = True + if hasattr(instance, "no_post_process"): + instance.no_post_process() + else: + instance.skip_history_when_saving = True + instance._post_saved_geo = True instance._cached_label_checked = False instance.save() if hasattr(instance, "cascade_update"): -- cgit v1.2.3