From 1df1a8c8130e5a9a1bdac736979ba24f02369c40 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 5 Feb 2026 17:19:07 +0100 Subject: 🚑️ imports: fix concatenation of existing fields - fix concat string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- archaeological_finds/tests.py | 40 +++++++++++++++++ archaeological_finds/tests/MCC-finds-example.csv | 8 ++-- ishtar_common/data_importer.py | 50 +++++++++++----------- .../fixtures/initial_importtypes-tests-fr.json | 2 +- 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py index 7c0c83575..6e62bb8ce 100644 --- a/archaeological_finds/tests.py +++ b/archaeological_finds/tests.py @@ -1003,6 +1003,46 @@ class ImportFindTest(BaseImportFindTest): # check errors self.assertEqual(len(impt.errors), 0) + def test_import_string_concat(self): + self.init_context_record() + + MCC = ImporterType.objects.get(name="MCC - Mobilier") + # column : description + col = ImporterColumn.objects.get(col_number=23, importer_type_id=MCC.pk) + col.targets.update(concat=True, concat_str=" - ") + + mcc_file = open( + settings.LIB_BASE_PATH + "archaeological_finds/tests/MCC-finds-example.csv", + "rb", + ) + file_dict = { + "imported_file": SimpleUploadedFile(mcc_file.name, mcc_file.read()), + } + post_dict = { + "importer_type": MCC.pk, + "skip_lines": 1, + "encoding": "utf-8", + "name": "init_find_import", + "csv_sep": ",", + } + form = forms_common.BaseImportForm( + data=post_dict, files=file_dict, user=self.user + ) + form.is_valid() + self.assertTrue(form.is_valid()) + impt = form.save(self.ishtar_user) + impt.conservative_import = True + impt.save() + impt.initialize() + # import 2 times the description field + impt.importation() + impt.importation() + for find in models.Find.objects.filter(imports__pk=impt.pk).all(): + sp = find.description.split(" - ") + self.assertEqual(len(sp), 2) + self.assertNotEqual(sp[0], "") + self.assertEqual(sp[0], sp[1]) + class ImportFindLiveServerTest(LiveServerTestCase, BaseImportFindTest): diff --git a/archaeological_finds/tests/MCC-finds-example.csv b/archaeological_finds/tests/MCC-finds-example.csv index 86a572657..9e73d0424 100644 --- a/archaeological_finds/tests/MCC-finds-example.csv +++ b/archaeological_finds/tests/MCC-finds-example.csv @@ -1,5 +1,5 @@ code OA,numero INSEE commune,identifiant parcelle,identifiant UE,identifiant materiel,objet lot,partage,composite,matiere,type,determination,numero contenant,nombre fragment,poids,unite poids,date decouverte,etat sanitaire,type preservation a envisager,commentaire,chronologie,localisation topographique,interet particulier,description,remontage,photo -4200,75101,XXXX,HC,1,lot,non,,terre cuite,céramique,sfq,1,76,4040,g,,sais pas,,Blah,med,,,,, -4200,75101,XXXX,H.-C.,1,lot,non,,terre cuite,céramique,qsdfsqfd,1,56,2280,g,,,,,med,,,,, -4200,59350,YY55,US17,1,lot,non,,terre cuite,céramique,sqfdsq,2,44,5210,g,,stable,,,GR,,,,, -4200,59350,YY55,US17,2,lot,non,,terre cuite & verre,céramique,sqfdsq,45,43,1500,g,,,,,,,,,,image-1.jpg +4200,75101,XXXX,HC,1,lot,non,,terre cuite,céramique,sfq,1,76,4040,g,,sais pas,,Blah,med,,,Description 1,, +4200,75101,XXXX,H.-C.,1,lot,non,,terre cuite,céramique,qsdfsqfd,1,56,2280,g,,,,,med,,,Description 2,, +4200,59350,YY55,US17,1,lot,non,,terre cuite,céramique,sqfdsq,2,44,5210,g,,stable,,,GR,,,Description 3,, +4200,59350,YY55,US17,2,lot,non,,terre cuite & verre,céramique,sqfdsq,45,43,1500,g,,,,,,,,Description 4,,image-1.jpg diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py index 7bdade5ab..584917c8e 100644 --- a/ishtar_common/data_importer.py +++ b/ishtar_common/data_importer.py @@ -1568,7 +1568,7 @@ class Importer(object): field_name = field_name[idx_fields] if type(force_new) in (list, tuple): force_new = force_new[idx_fields] - if formater.concat: + if formater.concat and any(formater.concat): self.concats.add(field_name) concat_str = formater.concat_str if type(formater.concat_str) in (list, tuple): @@ -2141,42 +2141,40 @@ class Importer(object): raise self._get_does_not_exist_in_db_error(cls, dct) dct["defaults"] = defaults.copy() - if not created and not path and self.UNICITY_KEYS: + # manage default values and concatenation + if not created and not path and self.UNICITY_KEYS and obj is not None: updated_dct = {} - if self.conservative_import: - for k in dct["defaults"]: - new_val = dct["defaults"][k] - if new_val is None or new_val == "": - continue - val = getattr(obj, k) - if val is None or val == "": - updated_dct[k] = new_val - elif ( - k in self.concats - and type(val) == str - and type(new_val) == str - ): - updated_dct[k] = val + "\n" + new_val - else: - for k in dct["defaults"]: - new_val = dct["defaults"][k] - if new_val is None or new_val == "": - continue - if obj and k == "data": - updated_dct[k] = update_data(obj.data, new_val) - else: - updated_dct[k] = new_val + for k in dct["defaults"]: + new_val = dct["defaults"][k] + if new_val is None or new_val == "": + continue + val = getattr(obj, k) + if val is None or val == "": + updated_dct[k] = new_val + elif obj and k == "data": + updated_dct[k] = update_data(obj.data, new_val) + elif ( + k in self.concats + and type(val) == str + and type(new_val) == str + ): + sep = "" + if k in self.concat_str: + sep = self.concat_str[k] + updated_dct[k] = val + sep + new_val if updated_dct: if self.simulate: self.updated_objects[-1][-1] = updated_dct else: + obj.__class__.objects.filter(pk=obj.pk).update( + **updated_dct + ) for k in updated_dct: setattr(obj, k, updated_dct[k]) obj._timestamp = self.timestamp obj._queue = "low_priority" if hasattr(obj, "no_post_process"): obj.no_post_process(history=True) - obj.save() if ( not self.simulate and self.import_instance diff --git a/ishtar_common/fixtures/initial_importtypes-tests-fr.json b/ishtar_common/fixtures/initial_importtypes-tests-fr.json index eadf26ff5..f8e000cd3 100644 --- a/ishtar_common/fixtures/initial_importtypes-tests-fr.json +++ b/ishtar_common/fixtures/initial_importtypes-tests-fr.json @@ -2047,7 +2047,7 @@ "mcc-mobilier", 23 ], - "target": "base_finds__description", + "target": "description", "formater_type": [ "UnicodeFormater", "1000", -- cgit v1.2.3