diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-09-22 10:51:51 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-09-22 10:51:51 +0200 |
commit | d6e79554718fb618425b3c7085427d170ecf79f0 (patch) | |
tree | 46aa30bd3d9f466611159632a214911bda162837 | |
parent | deaf4b714e0f26caeac743ad88937f1c92de6b48 (diff) | |
download | Ishtar-d6e79554718fb618425b3c7085427d170ecf79f0.tar.bz2 Ishtar-d6e79554718fb618425b3c7085427d170ecf79f0.zip |
✨ imports: manage post processing of linked items - post importer for Parcel: set_parcel
-rw-r--r-- | archaeological_operations/models.py | 18 | ||||
-rw-r--r-- | ishtar_common/data_importer.py | 29 |
2 files changed, 42 insertions, 5 deletions
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index f4430a8f1..f8c8f20a0 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -20,6 +20,7 @@ from collections import OrderedDict import datetime from itertools import groupby +import re import uuid from django.apps import apps @@ -34,6 +35,7 @@ from django.db.models import Q, Count, Sum, Max, Avg from django.db.models.signals import post_save, m2m_changed, post_delete from django.forms import ValidationError from django.urls import reverse +from ishtar_common.data_importer import post_importer_action from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy, get_generated_id from ishtar_common.models import ( @@ -3345,6 +3347,22 @@ class Parcel(LightHistorizedItem): def __str__(self): return self.short_label + @post_importer_action + def set_parcel(self, __, value): + """ + Set section and parcel number from a string + """ + RE_PARCEL = re.compile(r"([A-Za-z]{1,4})(\d+)") + m = RE_PARCEL.match(value) + if not m: + return + self.section, self.parcel_number = m.groups() + self.__class__.objects.filter(pk=self.pk).update( + section=self.section, parcel_number=self.parcel_number + ) + + set_parcel.post_save = True + def natural_key(self): return (self.uuid,) diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py index 4285a658b..7717c0e03 100644 --- a/ishtar_common/data_importer.py +++ b/ishtar_common/data_importer.py @@ -32,7 +32,7 @@ from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.contrib.gis.geos.error import GEOSException from django.db.models.fields import FieldDoesNotExist -from django.core.exceptions import FieldError +from django.core.exceptions import FieldError, MultipleObjectsReturned from django.core.files import File from django.db import IntegrityError, DatabaseError, transaction from django.db.models import Q @@ -881,10 +881,29 @@ class Importer(object): def post_processing(self, idx_line, item): # force django based post-processing for the item item = item.__class__.objects.get(pk=item.pk) - for func, context, value in self._item_post_processing: + for cls, func, context, value in self._item_post_processing: context["import_object"] = self.import_instance + if cls != item.__class__: + # try to get associated item + current_item = None + for id_key in ("id", "pk", "external_id"): + if context.get(id_key, None): + try: + current_item = cls.objects.get(**{id_key: context[id_key]}) + except (cls.DoesNotExist, MultipleObjectsReturned) as __: + break + if not current_item: + self.errors.append( + (idx_line, None, + str(_("Item {} with values: {} not identified for post-treatment - need a non ambiguous key")).format( + cls.__name__, str(context) + )) + ) + continue + else: + current_item = item try: - f = getattr(item, func) + f = getattr(current_item, func) returned = f(context, value) if returned and not getattr(f, "_no_repost_save", False): if not isinstance(returned, Iterable): @@ -1215,7 +1234,7 @@ class Importer(object): self._throughs = [] # list of (formater, value) self._post_processing = [] # list of (formater, value) - self._item_post_processing = [] + self._item_post_processing = [] # cls, attribute, data, value data = {} self.current_csv_line = None @@ -1811,7 +1830,7 @@ class Importer(object): if func.importer_trigger == "pre": func(data, data[attribute]) elif func.importer_trigger == "post": - self._item_post_processing.append([attribute, data, data[attribute]]) + self._item_post_processing.append([cls, attribute, data, data[attribute]]) else: logger.warning( "Unknow importer_trigger '{}' for '{}'".format( |