diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2026-05-01 17:40:56 +0200 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2026-05-01 18:00:46 +0200 |
| commit | 0ade281776ba2ed0775e944a38fea9d8b33eb05c (patch) | |
| tree | a6690a5401a8c024443cba94e056b5a9f625abd4 | |
| parent | 77d3051ee44df36c37522af9f1c610a2d1fac163 (diff) | |
| download | Ishtar-0ade281776ba2ed0775e944a38fea9d8b33eb05c.tar.bz2 Ishtar-0ade281776ba2ed0775e944a38fea9d8b33eb05c.zip | |
🐛 search: fix search with many wildcard characters
| -rw-r--r-- | archaeological_operations/tests.py | 9 | ||||
| -rw-r--r-- | ishtar_common/views_item.py | 51 |
2 files changed, 46 insertions, 14 deletions
diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 136f710f1..953229dbc 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -3245,8 +3245,10 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText, StatisticsTes ope1.year = 2042 ope1.end_date = "2010-01-01" + ope1.common_name = "Opération : Château de Fougères" ope1.save() ope2.year = 2020 + ope2.common_name = "Opération : Château de Josselin" ope2.save() # ope3.year: 2018 @@ -3340,6 +3342,13 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText, StatisticsTes '{}*'.format(neo.label[:3]), 2, "Open search") """ + # many open search + search_name_q = str(pgettext("key for text search", "name")) + result = [ + (f'{search_name_q}="Foug*" {search_name_q}="Jossel*"', 2), + ] + self._test_search(c, result, context="Many name open search") + # non hierarchic search search_remain_q = str(pgettext("key for text search", "remain")) result = [ diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 7ad25876a..eb37c9d62 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -1599,6 +1599,18 @@ def _manage_hierarchic_fields(model, dct, and_reqs): break +def __dict_add(dct, key, value, merge_char=";"): + """ + Create dict entry if no value. + Merge with merge_char if a value exists. + """ + if key in dct: + dct[key] += merge_char + else: + dct[key] = "" + dct[key] += value + + def _manage_clean_search_field(dct, exclude=None, reverse=False, related_name_fields=None): related_names = related_name_fields if related_name_fields else [] for k in list(dct.keys()): @@ -1609,24 +1621,35 @@ def _manage_clean_search_field(dct, exclude=None, reverse=False, related_name_fi dct[k] = _clean_type_val(dct[k]) if "*" not in dct[k] or k.endswith("regex"): continue - value = dct.pop(k).strip() + + values = dct.pop(k).strip().split(";") base_key = k[:] if k.endswith("__iexact"): base_key = k[:-len("__iexact")] - if value == "*": - if k in related_names or not reverse: - dct[base_key + "__isnull"] = False - if exclude is not None and k.endswith("__iexact"): + + for value in values: + # get syntax for each value + if "*" not in value: + # this value has no wild card + __dict_add(dct, k, value) + continue + + if value == "*": + # search for exists or not exists + if k in related_names or not reverse: + dct[base_key + "__isnull"] = False + if exclude is not None and k.endswith("__iexact"): + exclude[base_key + "__exact"] = "" + continue + + if value.startswith("*"): + value = value[1:] + if value.endswith("*"): + value = value[:-1] + if value: + __dict_add(dct, base_key + "__icontains", value) + elif exclude is not None: exclude[base_key + "__exact"] = "" - continue - if value.startswith("*"): - value = value[1:] - if value.endswith("*"): - value = value[:-1] - if value: - dct[base_key + "__icontains"] = value - elif exclude is not None: - exclude[base_key + "__exact"] = "" def _get_relation_type_dict(my_relation_types_prefix, dct): |
