diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-05-29 11:10:50 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2024-05-30 14:20:27 +0200 |
commit | cb1e9f1f15c38f68c1859b2dfd67870b0ed81240 (patch) | |
tree | 415ec01bb56b837f5f951db06cd5a107a720f3fe /ishtar_common/views_item.py | |
parent | d949cd7866446e30ca3c14926358fc91f1535ded (diff) | |
download | Ishtar-cb1e9f1f15c38f68c1859b2dfd67870b0ed81240.tar.bz2 Ishtar-cb1e9f1f15c38f68c1859b2dfd67870b0ed81240.zip |
🐛 criteria search - towns - related model: fix * and - * (refs #5882)
Diffstat (limited to 'ishtar_common/views_item.py')
-rw-r--r-- | ishtar_common/views_item.py | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 1a35e766e..9f2fbb7b5 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -753,6 +753,8 @@ def _parse_query_string( dct = exc_dct if query_parameters[base_term].extra_query: dct.update(query_parameters[base_term].extra_query) + if query_parameters[base_term].related_name and query == '"*"': + term = query_parameters[base_term].related_name if term in dct: dct[term] += ";" + query else: @@ -1140,10 +1142,20 @@ def _manage_hierarchic_fields(model, dct, and_reqs): suffix = "label__iexact" else: continue - val = _clean_type_val(dct.pop(req)) if val.startswith('"') and val.endswith('"'): val = val[1:-1] + if val == "*": + req = req.replace("label__", "").replace("pk", "").replace("iexact", "") + req += "isnull" + reqs = Q(**{req: False}) + and_reqs.append(reqs) + continue + elif "*" in val and "iexact" in suffix: + suffix = suffix.replace("iexact", "icontains") + req = req.replace("iexact", "icontains") + val = val.replace("*", "") + reqs = Q(**{req: val}) for idx in range(HIERARCHIC_LEVELS): @@ -1154,12 +1166,18 @@ def _manage_hierarchic_fields(model, dct, and_reqs): # TODO: improve query with "IN ()"? continue - if req.endswith("wcontainer_id") or req.endswith("wcontainer_ref_id"): + if req.endswith("wcontainer_id") or req.endswith("wcontainer_ref_id"): val = _clean_type_val(dct.pop(req)).strip('"') if val.startswith('"') and val.endswith('"'): val = val[1:-1] vals = [v.replace('"', "") for v in val.split(";")] + req = req[1:] # remove "w" container_ids = [] + if "*" in vals: + main_req = Q(**{req + "__isnull": False}) + and_reqs.append(main_req) + continue + for val in vals: q = Container.objects.filter(cached_label__iexact=val).values_list( "id", flat=True) @@ -1167,7 +1185,6 @@ def _manage_hierarchic_fields(model, dct, and_reqs): continue container_id = q.all()[0] container_ids.append(container_id) - req = req[1:] # remove "w" main_req = Q(**{req + "__in": container_ids}) and_reqs.append(main_req) @@ -1215,15 +1232,29 @@ def _manage_hierarchic_fields(model, dct, and_reqs): vals = [v.replace('"', "") for v in val.split(";")] main_req = None for val in vals: + suf = suffix + if "*" == val: + req = req.replace("cached_label__", "").replace("pk", "").replace("iexact", "") + req += "isnull" + reqs = Q(**{req: False}) + if not main_req: + main_req = reqs + else: + main_req |= reqs + continue + elif "*" in val and "iexact" in suf: + suf = suffix.replace("iexact", "icontains") + req = req.replace("iexact", "icontains") + val = val.replace("*", "") reqs = Q(**{req: val}) nreq = base_req = req[:] for idx in range(HIERARCHIC_LEVELS): - nreq = nreq[: -(len(suffix))] + "parents__" + suffix + nreq = nreq[: -(len(suf))] + "parents__" + suf q = Q(**{nreq: val}) reqs |= q nreq = base_req[:] for idx in range(HIERARCHIC_LEVELS): - nreq = nreq[: -(len(suffix))] + "children__" + suffix + nreq = nreq[: -(len(suf))] + "children__" + suf q = Q(**{nreq: val}) reqs |= q if not main_req: @@ -1311,21 +1342,24 @@ def _manage_hierarchic_fields(model, dct, and_reqs): break -def _manage_clean_search_field(dct, exclude=None, reverse=False): +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()): # clean quoted search field - if type(dct[k]) != str: + if not isinstance(dct[k], str): continue dct[k] = dct[k].replace('"', "") dct[k] = _clean_type_val(dct[k]) - if "*" not in dct[k] or not k.endswith("__iexact"): + if "*" not in dct[k] or k.endswith("regex"): continue value = dct.pop(k).strip() - base_key = k[:-len("__iexact")] + base_key = k[:] + if k.endswith("__iexact"): + base_key = k[:-len("__iexact")] if value == "*": - if not reverse: + if k in related_names or not reverse: dct[base_key + "__isnull"] = False - if exclude is not None: + if exclude is not None and k.endswith("__iexact"): exclude[base_key + "__exact"] = "" continue if value.startswith("*"): @@ -2218,6 +2252,9 @@ def get_item( if k not in query_parameters: query_parameters[k] = SearchAltName(k, request_keys[k]) + related_name_fields = [query_parameters[k].related_name for k in query_parameters + if query_parameters[k].related_name] + dct, excluded_dct, distinct_queries = _search_manage_search_vector( model, dct, @@ -2273,8 +2310,8 @@ def get_item( exc_and_reqs += dct.pop("exc_and_reqs") updated_excluded = {} - _manage_clean_search_field(dct, updated_excluded) - _manage_clean_search_field(excluded_dct, dct, reverse=True) + _manage_clean_search_field(dct, updated_excluded, related_name_fields=related_name_fields) + _manage_clean_search_field(excluded_dct, dct, reverse=True, related_name_fields=related_name_fields) if updated_excluded: excluded_dct.update(updated_excluded) |