diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2025-10-06 20:49:48 +0200 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2025-11-29 17:07:10 +0100 |
| commit | 702d2f5356b35599cffdebd3f53a19c5e7412e82 (patch) | |
| tree | 44a6e56e8c47047726f05a4bc3bb1ec151a199ec | |
| parent | 47ae57c37abfed75f93594255b6c617afa011bf5 (diff) | |
| download | Ishtar-702d2f5356b35599cffdebd3f53a19c5e7412e82.tar.bz2 Ishtar-702d2f5356b35599cffdebd3f53a19c5e7412e82.zip | |
✨ find - statistics: add top container
| -rw-r--r-- | archaeological_finds/models_finds.py | 3 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 10 | ||||
| -rw-r--r-- | ishtar_common/views_item.py | 42 |
3 files changed, 43 insertions, 12 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 56232165f..2d96726ea 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1331,7 +1331,8 @@ class Find( "base_finds__context_record__operation__towns__areas__parent__label", _("Extended area"), ), - ("periods__label", _("Chronological period")), + ("container__cached_division__splitpart_|_1", _("Top container")), + ("datings__period__label", _("Chronological period")), ("material_types__label", _("Material type")), ("object_types__label", _("Object type")), ("recommended_treatments__label", _("Recommended treatments")), diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index bdd7a67e5..90ae08f0b 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -66,7 +66,7 @@ from django.core.files import File from django.core.files.storage import FileSystemStorage from django.core.validators import EMPTY_VALUES, MaxValueValidator from django.db import models -from django.db.models import Q +from django.db.models import Func, Q from django.db.models.functions import Length from django.http import HttpResponseRedirect from django.urls import re_path, reverse, NoReverseMatch @@ -199,6 +199,14 @@ class Round(models.Func): arg_joiner = "::numeric, " +class SplitPart(Func): + """ + PostgreSQL split part annotation + """ + function = 'split_part' + arity = 3 + + CSV_OPTIONS = {"delimiter": ",", "quotechar": '"', "quoting": QUOTE_ALL} diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 62de9b8b4..83c84ae78 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -46,6 +46,7 @@ from django.db.models import ( ExpressionWrapper, FloatField, FileField, + Value ) from django.db.models.functions import ExtractYear from django.db.utils import ProgrammingError @@ -82,8 +83,9 @@ from ishtar_common.utils import ( get_current_profile, HistoryError, PRIVATE_FIELDS, - SearchAltName, Round, + SearchAltName, + SplitPart, ) from .menus import Menu @@ -2102,10 +2104,19 @@ def _get_json_stats( value_keys = [] for stat in (stats_modality_1, stats_modality_2): if not stat: + value_keys.append(stat) continue if stat.endswith("__year"): q = q.annotate(**{stat: ExtractYear(stat[:-len("__year")])}) + if "__splitpart_" in stat: + st, args = stat.split("__splitpart_") + sep, index = args.split("_") + index = int(index) + stat = f"{st}_modality" + q = q.annotate(**{stat: SplitPart(F(st), Value(sep), index)}) value_keys.append(stat) + stats_modality_1, stats_modality_2 = value_keys + value_keys = [v for v in value_keys if v] value_keys.append(stats_sum_variable) q = q.values(*value_keys) data = [] @@ -2813,6 +2824,26 @@ def get_item( sub_items = sub_items.filter(base_query) if exc_query: sub_items = sub_items.exclude(exc_query) + stats_modality_1, stats_modality_2 = None, None + if data_type == "json-stats": + stats_modality_1 = request_items.get("stats_modality_1", None) + stats_modality_2 = request_items.get("stats_modality_2", None) + if ( + not stats_modality_1 + or stats_modality_1 not in model.STATISTIC_MODALITIES + ): + stats_modality_1 = model.STATISTIC_MODALITIES[0] + if stats_modality_2 not in model.STATISTIC_MODALITIES: + stats_modality_2 = None + if getattr(model, "STATISTIC_MODALITIES_QUERY", False): + if stats_modality_1 in model.STATISTIC_MODALITIES_QUERY and \ + "query" in model.STATISTIC_MODALITIES_QUERY[stats_modality_1]: + sub_items = sub_items.filter( + **model.STATISTIC_MODALITIES_QUERY[stats_modality_1]["query"]) + if stats_modality_2 in model.STATISTIC_MODALITIES_QUERY and \ + "query" in model.STATISTIC_MODALITIES_QUERY[stats_modality_2]: + sub_items = sub_items.filter( + **model.STATISTIC_MODALITIES_QUERY[stats_modality_2]["query"]) for extra in extras: sub_items = sub_items.extra(**extra) @@ -2860,15 +2891,6 @@ def get_item( # print(str(items.values("id").query)) if data_type == "json-stats": - stats_modality_1 = request_items.get("stats_modality_1", None) - stats_modality_2 = request_items.get("stats_modality_2", None) - if ( - not stats_modality_1 - or stats_modality_1 not in model.STATISTIC_MODALITIES - ): - stats_modality_1 = model.STATISTIC_MODALITIES[0] - if stats_modality_2 not in model.STATISTIC_MODALITIES: - stats_modality_2 = None stats_sum_variable = request_items.get("stats_sum_variable", None) stats_sum_variable_keys = list(model.STATISTIC_SUM_VARIABLE.keys()) if ( |
