diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2020-11-17 15:37:22 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-02-28 12:15:21 +0100 |
commit | 4fa501cb189c61d94a2ca53a604f3db7a212153c (patch) | |
tree | e983fd246f6fd2ce0e9521ea23c1f93c73cc8bc9 /ishtar_common | |
parent | a255ff5f509225c3258aa9546d9cbd4ce0c0fa0b (diff) | |
download | Ishtar-4fa501cb189c61d94a2ca53a604f3db7a212153c.tar.bz2 Ishtar-4fa501cb189c61d94a2ca53a604f3db7a212153c.zip |
Manage a "custom_index" for base types
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/migrations/0207_auto_20201117_1021.py | 70 | ||||
-rw-r--r-- | ishtar_common/models.py | 51 | ||||
-rw-r--r-- | ishtar_common/models_common.py | 84 |
3 files changed, 193 insertions, 12 deletions
diff --git a/ishtar_common/migrations/0207_auto_20201117_1021.py b/ishtar_common/migrations/0207_auto_20201117_1021.py new file mode 100644 index 000000000..bd6d970fe --- /dev/null +++ b/ishtar_common/migrations/0207_auto_20201117_1021.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.27 on 2020-11-17 10:21 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0206_auto_20201110_1030'), + ] + + operations = [ + migrations.RenameField( + model_name='ishtarsiteprofile', + old_name='context_record_complete_identifier', + new_name='contextrecord_complete_identifier', + ), + migrations.AddField( + model_name='document', + name='custom_index', + field=models.IntegerField(blank=True, null=True, verbose_name='Custom index'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='basefind_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage base find custom index.', verbose_name='Base find custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='container_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage container custom index.', verbose_name='Container custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='contextrecord_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage context record custom index.', verbose_name='Context record custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='document_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage document custom index.', verbose_name='Document custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='file_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage archaeological file custom index.', verbose_name='Archaeological file custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='find_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage find custom index.', verbose_name='Find custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='operation_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage operation custom index.', verbose_name='Operation custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='site_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage archaeological site custom index.', verbose_name='Archaeological site custom index key'), + ), + migrations.AddField( + model_name='ishtarsiteprofile', + name='warehouse_custom_index', + field=models.TextField(default='', help_text='Key to be used to manage warehouse custom index.', verbose_name='Warehouse custom index key'), + ), + ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index bba04488b..6e8e0409e 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -808,11 +808,20 @@ class IshtarSiteProfile(models.Model, Cached): _("Operation complete identifier"), default="", help_text=_("Formula to manage operation complete identifier.")) + operation_custom_index = models.TextField( + _("Operation custom index key"), + default="", + help_text=_("Key to be used to manage operation custom index.")) site_complete_identifier = models.TextField( _("Archaeological site complete identifier"), default="", help_text=_("Formula to manage archaeological site complete" " identifier.")) + site_custom_index = models.TextField( + _("Archaeological site custom index key"), + default="", + help_text=_("Key to be used to manage archaeological site custom" + " index.")) file_external_id = models.TextField( _("File external id"), default="{year}-{numeric_reference}", @@ -825,6 +834,11 @@ class IshtarSiteProfile(models.Model, Cached): default="", help_text=_("Formula to manage archaeological file complete " "identifier.")) + file_custom_index = models.TextField( + _("Archaeological file custom index key"), + default="", + help_text=_("Key to be used to manage archaeological file custom " + "index.")) parcel_external_id = models.TextField( _("Parcel external id"), default="{associated_file__external_id}{operation__code_patriarche}-" @@ -840,10 +854,14 @@ class IshtarSiteProfile(models.Model, Cached): "Change this with care. With incorrect formula, the " "application might be unusable and import of external " "data can be destructive.")) - context_record_complete_identifier = models.TextField( + contextrecord_complete_identifier = models.TextField( _("Context record complete identifier"), default="", help_text=_("Formula to manage context record complete identifier.")) + contextrecord_custom_index = models.TextField( + _("Context record custom index key"), + default="", + help_text=_("Key to be used to manage context record custom index.")) base_find_external_id = models.TextField( _("Base find external id"), default="{context_record__external_id}-{label}", @@ -855,6 +873,10 @@ class IshtarSiteProfile(models.Model, Cached): _("Base find complete identifier"), default="", help_text=_("Formula to manage base find complete identifier.")) + basefind_custom_index = models.TextField( + _("Base find custom index key"), + default="", + help_text=_("Key to be used to manage base find custom index.")) find_external_id = models.TextField( _("Find external id"), default="{get_first_base_find__context_record__external_id}-{label}", @@ -866,6 +888,10 @@ class IshtarSiteProfile(models.Model, Cached): _("Find complete identifier"), default="", help_text=_("Formula to manage find complete identifier.")) + find_custom_index = models.TextField( + _("Find custom index key"), + default="", + help_text=_("Key to be used to manage find custom index.")) container_external_id = models.TextField( _("Container external id"), default="{parent_external_id}-{container_type__txt_idx}-" @@ -878,6 +904,10 @@ class IshtarSiteProfile(models.Model, Cached): _("Container complete identifier"), default="", help_text=_("Formula to manage container complete identifier.")) + container_custom_index = models.TextField( + _("Container custom index key"), + default="", + help_text=_("Key to be used to manage container custom index.")) warehouse_external_id = models.TextField( _("Warehouse external id"), default="{name|slug}", @@ -889,6 +919,10 @@ class IshtarSiteProfile(models.Model, Cached): _("Warehouse complete identifier"), default="", help_text=_("Formula to manage warehouse complete identifier.")) + warehouse_custom_index = models.TextField( + _("Warehouse custom index key"), + default="", + help_text=_("Key to be used to manage warehouse custom index.")) document_external_id = models.TextField( _("Document external id"), default="{index}", @@ -900,6 +934,10 @@ class IshtarSiteProfile(models.Model, Cached): _("Document complete identifier"), default="", help_text=_("Formula to manage document complete identifier.")) + document_custom_index = models.TextField( + _("Document custom index key"), + default="", + help_text=_("Key to be used to manage document custom index.")) person_raw_name = models.TextField( _("Raw name for person"), default="{name|upper} {surname}", @@ -3036,6 +3074,17 @@ class Document(BaseHistorizedItem, CompleteIdentifierItem, OwnPerms, ImageModel, def __str__(self): return self.title + def get_index_operation(self): + current_operation = None + ope_nb = self.operations.count() + if ope_nb > 1: + return + elif ope_nb == 1: + key = 'operations__pk' + cr_nb = self.context_records.count() + if cr_nb: + self.context_records + def natural_key(self): return (self.external_id,) diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index d2e118c7a..4abc81a76 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -42,7 +42,7 @@ from django.core.serializers import serialize from django.core.urlresolvers import reverse, NoReverseMatch from django.core.validators import validate_slug from django.db import connection -from django.db.models import Q, Count +from django.db.models import Q, Count, Max from django.db.models.signals import post_save, post_delete, m2m_changed from django.template.defaultfilters import slugify from django.utils.safestring import SafeText, mark_safe @@ -62,15 +62,6 @@ from ishtar_common.utils import get_cache, disable_for_loaddata, \ get_all_field_names, merge_tsvectors, cached_label_changed, post_save_geo, \ task, duplicate_item, get_generated_id, get_current_profile -""" -from ishtar_common.models import get_external_id, \ - LightHistorizedItem, OwnPerms, Address, post_save_cache, \ - DashboardFormItem, document_attached_changed, SearchAltName, \ - DynamicRequest, GeoItem, QRCodeItem, SearchVectorConfig, DocumentItem, \ - QuickAction, MainItem, Merge - - -""" logger = logging.getLogger(__name__) @@ -637,6 +628,18 @@ class HierarchicalType(GeneralType): lbls.append(item.label) return " > ".join(reversed(lbls)) + @property + def first_parent(self): + parent = self.parent + parents = [] + while parent: + if parent in parents: # prevent circular + return parent + parents.append(parent) + if not parent.parent: + return parent + parent = parent.parent + class StatisticItem: STATISTIC_MODALITIES = [] # example: "year", "operation_type__label" @@ -2645,6 +2648,7 @@ class CompleteIdentifierItem(models.Model, ImageContainerModel): HAS_QR_CODE = True complete_identifier = models.TextField(_("Complete identifier"), blank=True, null=True) + custom_index = models.IntegerField("Custom index", blank=True, null=True) qrcode = models.ImageField(upload_to=get_image_path, blank=True, null=True, max_length=255) @@ -2707,9 +2711,67 @@ class CompleteIdentifierItem(models.Model, ImageContainerModel): complete_identifier = getattr(self, cached_label_key) return complete_identifier + def generate_custom_index(self, force=False): + if not self.pk: + return + if self.custom_index and not force: + return self.custom_index + SLUG = getattr(self, "SLUG", None) + if not SLUG: + return + k = SLUG + "_custom_index" + profile = get_current_profile() + if not hasattr(profile, k): + return + key = getattr(profile, k) + if not key or not key.strip(): + return + keys = key.strip().split(";") + if len(key) == 1 and hasattr(self, "get_index_" + key): # custom index + # generation + return getattr(self, "get_index_" + key)() + model = self.__class__ + try: + self_keys = set( + list(model.objects.filter(pk=self.pk).values_list(*keys))) + except Exception: # bad settings - not managed here + return + if len(self_keys) != 1: # key is not distinct + return + self_key = self_keys.pop() + return self._get_index(keys, self_key) + + def _get_index(self, keys: list, self_keys: list): + model = self.__class__ + q = model.objects + if self.pk: + q = model.objects.exclude(pk=self.pk) + for idx, key in enumerate(keys): + q = q.filter(**{key: self_keys[idx]}) + try: + r = q.aggregate(max_index=Max('custom_index')) + except Exception: # bad settings + return + if not r['max_index']: + return 1 + return r['max_index'] + 1 + def save(self, *args, **kwargs): - self.complete_identifier = self.generate_complete_identifier() super(CompleteIdentifierItem, self).save(*args, **kwargs) + if getattr(self, "_prevent_loop", False): + return + modified = False + custom_index = self.generate_custom_index() + if custom_index != self.custom_index: + modified = True + self.custom_index = custom_index + complete_id = self.generate_complete_identifier() + if complete_id: + modified = True + self.complete_identifier = complete_id + if modified: + self._prevent_loop = True + self.save() class SearchVectorConfig: |