diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-11-14 18:53:00 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2023-11-15 11:15:48 +0100 |
commit | cbe5632f6be526afa0e2ff0bb58c0cad3070b8b8 (patch) | |
tree | a724a24748f762f40e1f57fc53b5a39d20861925 | |
parent | b434924e40795014617a57f616d164cdad6c430d (diff) | |
download | Ishtar-cbe5632f6be526afa0e2ff0bb58c0cad3070b8b8.tar.bz2 Ishtar-cbe5632f6be526afa0e2ff0bb58c0cad3070b8b8.zip |
🐛 search: fix -type="*" search for types with no hierarchy
-rw-r--r-- | archaeological_operations/tests.py | 19 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 75 |
2 files changed, 77 insertions, 17 deletions
diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 331c24659..afa484839 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -3190,6 +3190,25 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): ] self._test_search(c, result, context="Facet search with * characters") + def test_search_has_type_filled_or_not(self): + c = Client() + c.login(username=self.username, password=self.password) + ope = self.operations[0] + ope.report_processing = models.ReportState.objects.all()[0] + ope.save() + final_neo = models.Period.objects.get(txt_idx="final-neolithic") + ope.periods.add(final_neo) + nb = models.Operation.objects.count() + self.assertTrue(nb > 1) + + search_name_q = str(pgettext("key for text search", "report-processing")) + result = [(f'{search_name_q}="*"', 1), (f'-{search_name_q}="*"', nb - 1)] + self._test_search(c, result, context="Search filled or not - simple type") + + search_name_q = str(pgettext_lazy("key for text search", "period")) + result = [(f'{search_name_q}="*"', 1), (f'-{search_name_q}="*"', nb - 1)] + self._test_search(c, result, context="Search filled or not - hierarchical type") + def test_hierarchic_search(self): ope = self.operations[1] c = Client() diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index e60358913..d80de34c7 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -537,16 +537,43 @@ def revert_item(model): HIERARCHIC_LEVELS = 5 -HIERARCHIC_FIELDS = [ - "periods", - "period", - "unit", - "material_types", - "material_type", - "conservatory_state", - "object_types", - "source_type", -] + +LIST_FIELDS = { # key: hierarchic depth + "periods": HIERARCHIC_LEVELS, + "period": HIERARCHIC_LEVELS, + "unit": HIERARCHIC_LEVELS, + "material_types": HIERARCHIC_LEVELS, + "material_type": HIERARCHIC_LEVELS, + "conservatory_state": HIERARCHIC_LEVELS, + "object_types": HIERARCHIC_LEVELS, + "source_type": HIERARCHIC_LEVELS, + "batch": 0, + "preservation_to_considers": 0, + "integrities": 0, + "remarkabilities": 0, + "checked_type": 0, + "material_type_quality": 0, + "object_type_quality": 0, + "communicabilities": 0, + "alterations": 0, + "alteration_causes": 0, + "treatment_emergency": 0, + "cultural_attributions": 0, + "remains": 0, + "dating_type": 0, + "quality": 0, + "operation_type": 0, + "report_processing": 0, + "record_quality_type": 0, + "data_type": 0, + "origin": 0, + "provider": 0, + "excavation_technics": 0, + "activity": 0, + "identification": 0, +} + +HIERARCHIC_FIELDS = list(LIST_FIELDS.keys()) def _get_values(request, val): @@ -1193,19 +1220,33 @@ def _manage_hierarchic_fields(model, dct, and_reqs): # manage search text by label if "*" in val: suffix = lbl_name + "__icontains" - val = val.replace("*", "") else: suffix = lbl_name + "__iexact" + current_values = val.strip().split("*") req = req[: -(len(base_suffix))] + suffix + else: + current_values = [val] + new_req = None + for idx, nval in enumerate(current_values): + if not idx: + new_req = Q(**{req: nval}) + else: + new_req &= Q(**{req: nval}) if not reqs: - reqs = Q(**{req: val}) + reqs = new_req else: - reqs |= Q(**{req: val}) - for idx in range(HIERARCHIC_LEVELS): + reqs |= new_req + hierarchic_levels = LIST_FIELDS[k_hr] if k_hr in LIST_FIELDS \ + else HIERARCHIC_LEVELS + for idx in range(hierarchic_levels): req = req[: -(len(suffix))] + "parent__" + suffix - q = Q(**{req: val}) - reqs |= q + for idx, nval in enumerate(current_values): + if not idx: + new_req = Q(**{req: nval}) + else: + new_req &= Q(**{req: nval}) + reqs |= new_req # TODO: improve query with "IN ()"? if reqs: and_reqs.append(reqs) @@ -1976,7 +2017,7 @@ def get_item( continue key = k[:] if key.startswith("searchprefix_"): - key = key[len("searchprefix_") :] + key = key[len("searchprefix_"):] dct_request_items[key] = request_items[k] request_items = dct_request_items |