diff options
| -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(  | 
