diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/fixtures/initial_importtypes-tests-fr.json | 4 | ||||
| -rw-r--r-- | ishtar_common/migrations/0270_gis_import_key_init.py | 11 | ||||
| -rw-r--r-- | ishtar_common/migrations/0272_ishtarsiteprofile_dating_external_id.py | 18 | ||||
| -rw-r--r-- | ishtar_common/models.py | 22 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 22 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/sheet_dating_list.html | 6 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 27 | ||||
| -rw-r--r-- | ishtar_common/utils_migrations.py | 39 |
8 files changed, 129 insertions, 20 deletions
diff --git a/ishtar_common/fixtures/initial_importtypes-tests-fr.json b/ishtar_common/fixtures/initial_importtypes-tests-fr.json index e8bdb40f9..244516a25 100644 --- a/ishtar_common/fixtures/initial_importtypes-tests-fr.json +++ b/ishtar_common/fixtures/initial_importtypes-tests-fr.json @@ -1349,13 +1349,13 @@ "mcc-ue", 13 ], - "target": "datings__period", + "target": "periods", "formater_type": [ "TypeFormater", "archaeological_operations.models.Period", "&" ], - "force_new": true, + "force_new": false, "concat": false, "concat_str": null, "comment": "" diff --git a/ishtar_common/migrations/0270_gis_import_key_init.py b/ishtar_common/migrations/0270_gis_import_key_init.py index ed3d8e568..030db3a25 100644 --- a/ishtar_common/migrations/0270_gis_import_key_init.py +++ b/ishtar_common/migrations/0270_gis_import_key_init.py @@ -1,16 +1,17 @@ +import sys from django.db import migrations -from ishtar_common.utils_migrations import update_import_key +from ishtar_common.utils_migrations import update_import_key, print_progress def update_importkey(apps, __): updated = 0 GeoVectorData = apps.get_model("ishtar_common", "geovectordata") - for data in GeoVectorData.objects.all(): + total = GeoVectorData.objects.count() + sys.stdout.write("\n") + for idx, data in enumerate(GeoVectorData.objects.all()): + print_progress(idx, total) updated += 1 if update_import_key(data) else 0 - if updated: - print() - print(f"* {updated} GeoVectorData import_key updated") class Migration(migrations.Migration): diff --git a/ishtar_common/migrations/0272_ishtarsiteprofile_dating_external_id.py b/ishtar_common/migrations/0272_ishtarsiteprofile_dating_external_id.py new file mode 100644 index 000000000..a3c8f278a --- /dev/null +++ b/ishtar_common/migrations/0272_ishtarsiteprofile_dating_external_id.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.19 on 2025-10-29 10:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0271_import_import_immediatly'), + ] + + operations = [ + migrations.AddField( + model_name='ishtarsiteprofile', + name='dating_external_id', + field=models.TextField(default='{{parent_external_id}}-{% if reference %}{{reference}}{% else %}{{auto_id}}{% endif %}', help_text='Formula to manage dating external ID. Change this with care. With incorrect formula, the application might be unusable and import of external data can be destructive.', verbose_name='Dating external id'), + ), + ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 0ffb24882..aa9224be7 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -423,11 +423,14 @@ class HistoryModel(models.Model): models = import_module(models) model = getattr(models, self.__class__.__name__[len("Historical"):]) field = getattr(model, key) - if hasattr(field, "rel"): - field = field.rel + if not hasattr(field, "reverse"): + related_model = field.field.model else: - field = field.remote_field - related_model = field.model + if hasattr(field, "rel"): + field = field.rel + else: + field = field.remote_field + related_model = field.model return related_model.history_decompress(self.history_m2m[key], create=create) @@ -1525,6 +1528,17 @@ class IshtarSiteProfile(models.Model, Cached): "Formula to manage cached label. If not set a default formula is used." ), ) + dating_external_id = models.TextField( + _("Dating external id"), + default="{{parent_external_id}}-{% if reference %}{{reference}}" + "{% else %}{{auto_id}}{% endif %}", + help_text=_( + "Formula to manage dating external ID. " + "Change this with care. With incorrect formula, the " + "application might be unusable and import of external " + "data can be destructive." + ), + ) document_external_id = models.TextField( _("Document external id"), default="{index}", diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index be3e06848..821a89ac4 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -1891,9 +1891,25 @@ class BaseHistorizedItem( new_item.history_m2m = saved_m2m values = new_item.m2m_listing(hist_key, create=True) or [] hist_field = getattr(self, hist_key) - hist_field.clear() - for val in values: - hist_field.add(val) + if hasattr(hist_field, "clear"): + hist_field.clear() + for val in values: + hist_field.add(val) + continue + # manage related field (not real m2m) + # # clear removed values + for current_value in hist_field.all(): + current_values = current_value.history_compress() + has_value = False + # clear non existant + for idx, value in enumerate(values[:]): + if value.history_compress() == current_values: + values.pop(idx) # remove existing to not create them + has_value = True + break + if has_value: + continue + current_value.delete() # force label regeneration self._cached_label_checked = False self.save() diff --git a/ishtar_common/templates/ishtar/blocks/sheet_dating_list.html b/ishtar_common/templates/ishtar/blocks/sheet_dating_list.html index 6135bbf77..e79d9f201 100644 --- a/ishtar_common/templates/ishtar/blocks/sheet_dating_list.html +++ b/ishtar_common/templates/ishtar/blocks/sheet_dating_list.html @@ -1,6 +1,7 @@ {% load i18n %} <table id='{{window_id}}-datings' class="table table-striped"> <tr> + <th>{% trans "Reference" %}</th> <th>{% trans "Chronological period" %}</th> <th>{% trans "Start date" %}</th> <th>{% trans "End date" %}</th> @@ -11,7 +12,10 @@ {% for dating in dating_list %} <tr> <td> - {{dating.period}} + {{dating.reference|default:"-"}} + </td> + <td> + {{dating.period|default:"-"}} </td> <td> {{dating.start_date|default_if_none:"-"}} diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 937b9bb99..bd79814e9 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -2373,11 +2373,7 @@ def get_urls_for_model( return urls -def m2m_historization_changed(sender, **kwargs): - obj = kwargs.get("instance", None) - if not obj: - return - obj._queue = kwargs.get("queue", settings.CELERY_DEFAULT_QUEUE) +def get_m2m_values(obj): hist_values = obj.history_m2m or {} for attr in obj.HISTORICAL_M2M: values = [] @@ -2387,6 +2383,12 @@ def m2m_historization_changed(sender, **kwargs): values.append(value.history_compress()) hist_values[attr] = values obj.history_m2m = hist_values + return hist_values + + +def manage_m2m(obj, kwargs): + obj._queue = kwargs.get("queue", settings.CELERY_DEFAULT_QUEUE) + hist_values = get_m2m_values(obj) if getattr(obj, "skip_history_when_saving", False): # assume the last modifier is good... q = obj.history.filter( @@ -2403,6 +2405,21 @@ def m2m_historization_changed(sender, **kwargs): obj.save() +def related_historization_changed(sender, **kwargs): + rel_obj = kwargs.get("instance", None) + if not rel_obj or not getattr(rel_obj, "CURRENT_MODEL_ATTR", None): + return + obj = getattr(rel_obj, rel_obj.CURRENT_MODEL_ATTR) + manage_m2m(obj, kwargs) + + +def m2m_historization_changed(sender, **kwargs): + obj = kwargs.get("instance", None) + if not obj: + return + manage_m2m(obj, kwargs) + + def max_size_help(help_for_doc=False): max_size = settings.MAX_UPLOAD_SIZE if help_for_doc: diff --git a/ishtar_common/utils_migrations.py b/ishtar_common/utils_migrations.py index 6d75ff885..04a6d9827 100644 --- a/ishtar_common/utils_migrations.py +++ b/ishtar_common/utils_migrations.py @@ -10,6 +10,9 @@ from django.core.management import call_command from django.db import connection from django.utils.translation import gettext_lazy +from ishtar_common.utils import BColors + + HOMEPAGE_TITLE = gettext_lazy("Welcome in Ishtar, open source software for management and inventory of archaeological data") @@ -233,3 +236,39 @@ def update_import_key(geovectordata): # 0267_gis_import_key GeoVectorData.objects.filter(pk=geovectordata.id).update( import_key=import_key) return True + + +def print_progress(idx, total): + sys.stdout.write(f"\r {BColors.OKBLUE}→ Migration {idx+1}/{total}{BColors.ENDC}") + + +def migrate_dating_periods(apps, model_dating, model, dating_attr): + if not hasattr(model, "datings_old"): # migration is not relevant anymore + return + q = model.objects.filter(datings_old__pk__isnull=False) + if not q.count(): + return + period_attr = ["start_date", "end_date", "dating_type", "quality", "precise_dating"] + full_period_attr = period_attr + ["period"] + sys.stdout.write("\n") + total = q.count() + for idx, item in enumerate(q.all()): + print_progress(idx, total) + for idx_dating, dating in enumerate(item.datings_old.all()): + if not dating.period: + # should not occur as for old dating period was required + continue + item.periods.add(dating.period) + has_more = False + for attr in period_attr: + if hasattr(dating, attr) and getattr(dating, attr): + has_more = True + break + if not has_more: + # do not recreate a new dating, it is not relevant anymore + continue + new_attrs = dict((k, getattr(dating, k)) for k in full_period_attr) + new_attrs[dating_attr] = item + new_attrs["external_id"] = f"{item.external_id}-{idx_dating + 1}" + model_dating.objects.create(**new_attrs) + |
