summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit0ade281776ba2ed0775e944a38fea9d8b33eb05c (patch)
treea6690a5401a8c024443cba94e056b5a9f625abd4
parent77d3051ee44df36c37522af9f1c610a2d1fac163 (diff)
downloadIshtar-0ade281776ba2ed0775e944a38fea9d8b33eb05c.tar.bz2
Ishtar-0ade281776ba2ed0775e944a38fea9d8b33eb05c.zip
🐛 search: fix search with many wildcard characters
-rw-r--r--archaeological_operations/tests.py9
-rw-r--r--ishtar_common/views_item.py51
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):