summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commitd6e79554718fb618425b3c7085427d170ecf79f0 (patch)
tree46aa30bd3d9f466611159632a214911bda162837
parentdeaf4b714e0f26caeac743ad88937f1c92de6b48 (diff)
downloadIshtar-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.py18
-rw-r--r--ishtar_common/data_importer.py29
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(