summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
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
commit53f899c9ded29921c982e67f220716b2f86823f3 (patch)
treee983fd246f6fd2ce0e9521ea23c1f93c73cc8bc9 /ishtar_common
parent9667957457eaf024e1b4a40f5d04ae001c4eeaca (diff)
downloadIshtar-53f899c9ded29921c982e67f220716b2f86823f3.tar.bz2
Ishtar-53f899c9ded29921c982e67f220716b2f86823f3.zip
Manage a "custom_index" for base types
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/migrations/0207_auto_20201117_1021.py70
-rw-r--r--ishtar_common/models.py51
-rw-r--r--ishtar_common/models_common.py84
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: