diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2026-06-23 10:28:33 +0200 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2026-06-23 10:28:33 +0200 |
| commit | bd5535ae6d66a1df704180d635c29abab8187197 (patch) | |
| tree | b6f101c8c686d8484bd72d9ef82490794a8e07aa | |
| parent | 447e92a636cf4f2bb29bcc7af2892d6914e3c24c (diff) | |
| download | Ishtar-bd5535ae6d66a1df704180d635c29abab8187197.tar.bz2 Ishtar-bd5535ae6d66a1df704180d635c29abab8187197.zip | |
🚑️ fix import deletion with item witch have associated datings
| -rw-r--r-- | ishtar_common/models_imports.py | 23 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 6 | ||||
| -rw-r--r-- | ishtar_common/views.py | 15 | ||||
| -rw-r--r-- | ishtar_common/wizards.py | 4 |
4 files changed, 46 insertions, 2 deletions
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py index d26a20791..b2966f578 100644 --- a/ishtar_common/models_imports.py +++ b/ishtar_common/models_imports.py @@ -48,6 +48,7 @@ from django.core.exceptions import ValidationError, SuspiciousOperation from django.core.files import File from django.core.files.base import ContentFile from django.core.validators import validate_comma_separated_integer_list, MinValueValidator +from django.db import transaction, IntegrityError from django.db.models import Q from django.db.models.base import ModelBase from django.db.models.signals import pre_delete @@ -2347,6 +2348,28 @@ class Import(BaseImport): self.parse_error_file() return bool(self.error_lines.filter(ignored=False).count()) + def delete(self, using=None, keep_parents=False) -> bool: + """ + Delete imported items one by one in order to prevent post save errors. + Mark each item for deletion with timestamp_label set to -1 (prevent + unecessary post_delete treatment - m2m_historization_changed and + related_historization_changed). + """ + try: + with transaction.atomic(): + for k in dir(self): + if not k.startswith("imported_archaeological_") and \ + not k.startswith("imported_ishtar_common_"): + continue + for idx, obj in enumerate(getattr(self, k).all()): + obj.__class__.objects.filter(pk=obj.pk).update( + timestamp_label=-1) + obj.delete() + super().delete(using=using, keep_parents=keep_parents) + return True + except IntegrityError: + return False + @property def pre_import_form_is_valid(self) -> bool: for column in self.importer_type.columns.filter(col_number__lte=0, required=True): diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 30bf4b7db..da7bf02f0 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -2421,6 +2421,9 @@ def related_historization_changed(sender, **kwargs): rel_obj, "__delete", False): return obj = getattr(rel_obj, rel_obj.CURRENT_MODEL_ATTR) + # object is been deleted + if obj.__class__.objects.filter(pk=obj.pk, timestamp_label=-1).count(): + return obj._post_save_geo_ok = True manage_m2m(obj, kwargs) @@ -2429,6 +2432,9 @@ def m2m_historization_changed(sender, **kwargs): obj = kwargs.get("instance", None) if not obj or getattr(obj, "__delete", False): return + # object is been deleted + if obj.__class__.objects.filter(pk=obj.pk, timestamp_label=-1).count(): + return manage_m2m(obj, kwargs) diff --git a/ishtar_common/views.py b/ishtar_common/views.py index e346e625d..dbaf8626b 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -2639,18 +2639,29 @@ class ImportMatchView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, Mo return reverse("import_link_unmatched", args=[self.kwargs["pk"]]) -class ImportDeleteView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, DeleteView): +class ImportDeleteView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, + DeleteView): template_name = "ishtar/import_delete.html" model = models.Import page_name = _("Delete import") permission_full = "ishtar_common.delete_import" permission_own = "delete_own_import" + def form_valid(self, form): + if not self.object.delete(): + messages.add_message( + self.request, messages.WARNING, + _("Integrity error - contact the administrator")) + return HttpResponseRedirect(self.request.path) + success_url = self.get_success_url() + return HttpResponseRedirect(success_url) + def get_success_url(self): return reverse("current_imports") -class ImportGroupDeleteView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, DeleteView): +class ImportGroupDeleteView(ImportPermissionMixin, IshtarMixin, LoginRequiredMixin, + DeleteView): template_name = "ishtar/import_delete.html" model = models.ImportGroup page_name = _("Delete import") diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 5e23d469a..2a2b396d4 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -1854,6 +1854,10 @@ class DeletionWizard(Wizard): def done(self, form_list, **kwargs): obj = self.get_current_object() if obj: + if hasattr(obj, "timestamp_label"): + # mark item for deletion with timestamp_label set to -1 + obj.__class__.objects.filter(pk=obj.pk).update( + timestamp_label=-1) try: obj.delete() except ObjectDoesNotExist: |
