summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_warehouse/models.py16
-rw-r--r--ishtar_common/models.py162
-rw-r--r--ishtar_common/models_common.py12
3 files changed, 168 insertions, 22 deletions
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index 35ef88147..093d56656 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -1322,6 +1322,22 @@ class Container(
def natural_key(self):
return (self.uuid,)
+ @property
+ def location_lbl(self):
+ return str(self.location or "")
+
+ @property
+ def responsability_lbl(self):
+ return str(self.responsibility or "")
+
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
+ if "simple" in kwargs:
+ keys = ["reference", "container_type", "code", "cached_location",
+ "cached_location", "index", "custom_index", "complete_identifier",
+ "responsability_lbl", "location_lbl"]
+ return self._get_values(keys, prefix=prefix, filtr=filtr, **kwargs)
+ return super().get_values(prefix, no_values, filtr, **kwargs)
+
@classmethod
@pre_importer_action
def import_get_location(cls, context, value):
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index af78961a3..dbd4ba72a 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -285,6 +285,7 @@ class ValueGetter:
"point",
"history_m2m",
]
+ GET_VALUES_DEFAULT = [] # empty values initialized
GET_VALUES_M2M = []
def _get_values_documents(self, prefix="", filtr=None):
@@ -314,11 +315,34 @@ class ValueGetter:
return
return [k[len(prefix):] for k in filtr if k.startswith(prefix)]
+ def _get_values(self, keys, prefix="", filtr=None, **kwargs):
+ """
+ Generic get values from a list of attributes.
+ """
+ values = {}
+ kw = copy.deepcopy(kwargs)
+ kw["simple"] = True
+ for key in keys:
+ if filtr and prefix + key not in filtr:
+ continue
+ value = getattr(self, key)
+ if hasattr(value, "get_values"):
+ value = value.get_values(prefix=prefix, no_values=True,
+ filtr=filtr, **kw)
+ elif hasattr(value, "all"):
+ value = [i.get_values(
+ prefix=prefix, no_values=True, filtr=filtr, **kw)
+ if hasattr(i, "get_values") else str(i) for i in value.all()]
+ else:
+ value = str(value) if value is not None else ""
+ values[prefix + key] = value
+ return values
+
def get_extra_values(self, prefix="", no_values=False, filtr=None, **kwargs):
return {}
def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
- if not prefix:
+ if not prefix and "simple" not in kwargs:
prefix = self._prefix
if not filtr:
filtr = []
@@ -335,6 +359,8 @@ class ValueGetter:
return values
exclude = kwargs.get("exclude", [])
values = {}
+ for key in self.GET_VALUES_DEFAULT:
+ values[key] = ""
if (
# qrcode for basefind is not relevant and interfere with find qrcode
getattr(self, "SLUG", "") != "basefind"
@@ -372,7 +398,11 @@ class ValueGetter:
new_exclude.append(s)
new_kwargs = kwargs.copy()
new_kwargs["exclude"] = new_exclude
- values.update(value.get_values(new_prefix, filtr=filtr, **kwargs))
+ new_value = value.get_values(new_prefix, filtr=filtr, **kwargs)
+ if isinstance(new_value, dict):
+ values.update(new_value)
+ else:
+ values[prefix + field_name] = new_value
if hasattr(self, "get_values_for_" + field_name):
values[prefix + field_name] = getattr(
self, "get_values_for_" + field_name
@@ -3151,6 +3181,23 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):
rights=["ishtar_common.change_person"],
)
QUICK_ACTIONS = [QA_EDIT]
+ GET_VALUES_EXCLUDE_FIELDS = [
+ "adminact_operation_in_charge", "adminact_scientist", "archived",
+ "author", "biographical_notes", "cached_profiles",
+ "context_record_excavation", "country", "created", "editors",
+ "exhibitions", "file_responsability", "gdpr_person",
+ "general_contractor_files", "history_creator", "history_creator_id",
+ "history_modifier", "history_modifier_id", "imports", "imports_updated",
+ "ishtar_users", "ishtaruser", "last_modified", "lock_user", "lock_user_id",
+ "locked", "manage_treatments", "merge_candidate", "merge_exclusion",
+ "merge_key", "minutes_writer", "need_update", "old_title",
+ "operation_collaborator", "operation_monitoring", "operation_protagonist",
+ "operation_scientist_responsability", "parcel_owner", "precise_town_id",
+ "profiles", "properties", "responsible_town_planning_service_files",
+ "salutation", "timestamp_geo", "timestamp_label",
+ "treatmentfile_applicant", "treatmentfile_responsability", "treatments",
+ "uuid", "warehouse_in_charge"
+ ]
objects = UUIDModelManager()
@@ -4659,7 +4706,7 @@ post_save.connect(post_save_cache, sender=AuthorType)
post_delete.connect(post_save_cache, sender=AuthorType)
-class Author(FullSearch):
+class Author(FullSearch, ValueGetter):
SLUG = "author"
PARENT_SEARCH_VECTORS = ["person"]
@@ -4709,6 +4756,10 @@ class Author(FullSearch):
+ list(self.contextrecordsource_related.all())
)
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
+ keys = ["author_type", "person"]
+ return self._get_values(keys, prefix, filtr, **kwargs)
+
def public_representation(self):
return {"type": str(self.author_type), "person": str(self.person)}
@@ -4838,6 +4889,7 @@ class SourceType(OrderedHierarchicalType):
help_text=_("Setting a language for this type of document is relevant"),
)
code = models.CharField(_("Code"), blank=True, default="", max_length=100)
+ GET_VALUES_EXTRA = ["code"]
class Meta:
verbose_name = _("Document type")
@@ -4845,6 +4897,19 @@ class SourceType(OrderedHierarchicalType):
ordering = ("parent__order", "parent__label", "order", "label",)
ADMIN_SECTION = _("Documents")
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
+ values = super().get_values(prefix, no_values, filtr, **kwargs)
+ if "no_hierarchy" in kwargs or not isinstance(values, dict) or \
+ "source_type_parent" not in values:
+ return values
+ result = []
+ v = copy.deepcopy(values)
+ while v.get("source_type_parent", None):
+ result.append(v["source_type_parent"]["source_type"])
+ v = v["source_type_parent"]
+ values["source_type_hierarchy"] = list(reversed(result))
+ return values
+
post_save.connect(post_save_cache, sender=SourceType)
post_delete.connect(post_save_cache, sender=SourceType)
@@ -5014,6 +5079,8 @@ class Document(
LINK_SPLIT = "<||>"
GET_VALUES_EXCLUDE_FIELDS = ValueGetter.GET_VALUES_EXCLUDE_FIELDS + [
+ "container_id",
+ "container_ref_id",
"warehouses",
"operations",
"treatments",
@@ -5554,7 +5621,7 @@ class Document(
class Meta:
verbose_name = _("Document")
verbose_name_plural = _("Documents")
- ordering = ("title",)
+ ordering = ("source_type__code", "custom_index", "title",)
permissions = (
("view_own_document", gettext("Can view own Document")),
("change_own_document", gettext("Can change own Document")),
@@ -5588,6 +5655,36 @@ class Document(
)
)
+ @property
+ def operations_full_lbl(self):
+ operations = list(self.operations.values_list("cached_label", flat=True).all())
+ return " ; ".join(sorted(operations))
+
+ @property
+ def context_records_full_lbl(self):
+ crs = list(self.context_records.values_list("cached_label", flat=True).all())
+ return " ; ".join(sorted(crs))
+
+ @property
+ def finds_full_lbl(self):
+ finds = list(self.finds.values_list("cached_label", flat=True).all())
+ return " ; ".join(sorted(finds))
+
+ @property
+ def operations_lbl(self):
+ operations = list(self.operations.values_list("code_patriarche", flat=True).all())
+ return " ; ".join(sorted(operations))
+
+ @property
+ def context_records_lbl(self):
+ crs = list(self.context_records.values_list("label", flat=True).all())
+ return " ; ".join(sorted(crs))
+
+ @property
+ def finds_lbl(self):
+ finds = list(self.finds.values_list("label", flat=True).all())
+ return " ; ".join(sorted(finds))
+
@post_importer_action
def set_main_image(self, __, value):
"""
@@ -5666,25 +5763,28 @@ class Document(
Context({"document": self})
)
- @property
- def container(self):
- if not self.container_id:
+ def _get_container(self, attr):
+ cache_attr = f"_{attr}"
+ if hasattr(self, cache_attr):
+ return getattr(self, cache_attr)
+ id_attr = f"{attr}_id"
+ if not getattr(self, id_attr):
+ setattr(self, cache_attr, None)
return
Container = apps.get_model("archaeological_warehouse", "Container")
try:
- return Container.objects.get(pk=self.container_id)
+ setattr(self, cache_attr, Container.objects.get(pk=getattr(self, id_attr)))
+ return getattr(self, cache_attr)
except Container.DoesNotExist:
return
@property
+ def container(self):
+ return self._get_container("container")
+
+ @property
def container_ref(self):
- if not self.container_ref_id:
- return
- Container = apps.get_model("archaeological_warehouse", "Container")
- try:
- return Container.objects.get(pk=self.container_ref_id)
- except Container.DoesNotExist:
- return
+ return self._get_container("container_ref")
@property
def pdf_attached(self):
@@ -5810,14 +5910,36 @@ class Document(
return ""
return self.image.path
+ GET_VALUES_DEFAULT = ["source_type_hierarchy"]
+
def get_extra_values(self, prefix="", no_values=False, filtr=None, **kwargs):
- values = {}
- if not filtr or prefix + "image_path" in filtr:
- values[prefix + "image_path"] = self.image_path
- if not filtr or prefix + "thumbnail_path" in filtr:
- values[prefix + "thumbnail_path"] = self.thumbnail_path
+ keys = ["image_path", "thumbnail_path", "authors", "operations_lbl",
+ "context_records_lbl", "finds_lbl", "operations_full_lbl",
+ "context_records_full_lbl", "finds_full_lbl"]
+ values = self._get_values(keys, prefix, filtr, **kwargs)
+ for attr in ("container", "container_ref"):
+ if filtr and attr not in filtr:
+ continue
+ values[attr] = {}
+ container = getattr(self, attr)
+ if container:
+ values[attr] = container.get_values(simple=True)
return values
+ get_extra_values.full_doc = _("""
+* `image_path`
+* `thumbnail_path`
+* `authors`
+* `container`
+* `container_ref`
+* `operations_lbl`
+* `operations_full_lbl`
+* `context_records_lbl`
+* `context_records_full_lbl`
+* `finds_lbl`
+* `finds_full_lbl`
+""")
+
@property
def images_without_main_image(self):
return []
diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py
index 573d4f8bf..de1de3a91 100644
--- a/ishtar_common/models_common.py
+++ b/ishtar_common/models_common.py
@@ -193,6 +193,7 @@ class GeneralType(Cached, models.Model):
available = models.BooleanField(_("Available"), default=True)
HELP_TEXT = ""
objects = TypeManager()
+ GET_VALUES_EXTRA = []
class Meta:
abstract = True
@@ -207,10 +208,15 @@ class GeneralType(Cached, models.Model):
return self.txt_idx
def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
+ if "simple" in kwargs:
+ return str(self)
dct = {}
if "parent_level" in kwargs and kwargs["parent_level"] > 5:
return dct
- if not prefix: # prefix is mandatory
+ for key in self.GET_VALUES_EXTRA:
+ p = (prefix[:]) if prefix else ""
+ dct[p + key] = str(getattr(self, key))
+ if not prefix or "simple" in kwargs: # prefix is mandatory
return dct
else:
dct[prefix[:-1]] = str(self)
@@ -220,8 +226,10 @@ class GeneralType(Cached, models.Model):
kwargs["parent_level"] += 1
else:
kwargs["parent_level"] = 1
+ kw = copy.deepcopy(kwargs)
+ kw["no_hierarchy"] = True
dct[prefix + "parent"] = self.parent.get_values(
- prefix=prefix + "parent_", no_values=no_values, filtr=filtr, **kwargs)
+ prefix=prefix, no_values=no_values, filtr=filtr, **kw)
return dct
@classmethod