diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/models.py | 21 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 3 | ||||
| -rw-r--r-- | ishtar_common/views_item.py | 63 | 
3 files changed, 70 insertions, 17 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py index d13b2eaa2..c098eee02 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2894,18 +2894,21 @@ class Person(Address, Merge, OwnPerms, ValueGetter, MainItem):              pgettext_lazy("key for text search", "email"), "email__iexact"          ),          "title": SearchAltName( -            pgettext_lazy("key for text search", "title"), "title__label__iexact" -        ), +            pgettext_lazy("key for text search", "title"), "title__label__iexact", +            related_name="title" +    ),          "salutation": SearchAltName(              pgettext_lazy("key for text search", "salutation"), "salutation__iexact"          ),          "person_types": SearchAltName(              pgettext_lazy("key for text search", "type"),              "person_types__label__iexact", +            related_name="person_types"          ),          "attached_to": SearchAltName(              pgettext_lazy("key for text search", "organization"),              "attached_to__cached_label__iexact", +            related_name="attached_to"          ),          "ishtaruser__isnull": SearchAltName(              pgettext_lazy("key for text search", "has-account"), @@ -4292,10 +4295,12 @@ class Document(          "authors": SearchAltName(              pgettext_lazy("key for text search", "author"),              "authors__cached_label__iexact", +            related_name="authors"          ),          "publisher": SearchAltName(              pgettext_lazy("key for text search", "publisher"),              "publisher__name__iexact", +            related_name="publisher"          ),          "publishing_year": SearchAltName(              pgettext_lazy("key for text search", "publishing-year"), @@ -4321,11 +4326,13 @@ class Document(              "description__iexact",          ),          "tag": SearchAltName( -            pgettext_lazy("key for text search", "tag"), "tags__label__iexact" +            pgettext_lazy("key for text search", "tag"), "tags__label__iexact", +            related_name="tags"          ),          "format": SearchAltName(              pgettext_lazy("key for text search", "format"),              "format_type__label__iexact", +            related_name="format_type"          ),          "support": SearchAltName(              pgettext_lazy("key for text search", "medium"), @@ -4338,6 +4345,7 @@ class Document(          "licenses": SearchAltName(              pgettext_lazy("key for text search", "license"),              "licenses__label__iexact", +            related_name="licenses"          ),          "rights_owner": SearchAltName(              pgettext_lazy("key for text search", "rights-owner"), @@ -4352,6 +4360,7 @@ class Document(          "associated_url": SearchAltName(              pgettext_lazy("key for text search", "url"),              "associated_url__iexact", +            related_name="associated_url"          ),          "isbn": SearchAltName(              pgettext_lazy("key for text search", "isbn"), "isbn__iexact" @@ -4388,6 +4397,7 @@ class Document(          "operation": SearchAltName(              pgettext_lazy("key for text search", "operation"),              "operations__cached_label__iexact", +            related_name="operations"          ),          "operations__operation_type": SearchAltName(              pgettext_lazy("key for text search", "operation-type"), @@ -4400,14 +4410,17 @@ class Document(          "context_record": SearchAltName(              pgettext_lazy("key for text search", "context-record"),              "context_records__cached_label__iexact", +            related_name="context_records"          ),          "find_basket": SearchAltName(              pgettext_lazy("key for text search", "basket-finds"),              "finds__basket__label__iexact", +            related_name="finds__basket"          ),          "find": SearchAltName(              pgettext_lazy("key for text search", "find"),              "finds__cached_label__iexact", +            related_name="finds"          ),          "find__denomination": SearchAltName(              pgettext_lazy("key for text search", "find-denomination"), @@ -4420,6 +4433,7 @@ class Document(          "containers": SearchAltName(              pgettext_lazy("key for text search", "container"),              "containers__cached_label__iexact", +            related_name="containers"          ),          "site": SearchAltName(              pgettext_lazy("key for text search", "site"), @@ -4432,6 +4446,7 @@ class Document(          "town": SearchAltName(              pgettext_lazy("key for text search", "town"),              "towns__name__iexact", +            related_name="towns"          ),          "area": SearchAltName(              pgettext_lazy("key for text search", "area"), diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index f58ff8f09..6abe515d6 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -1115,12 +1115,13 @@ class FullSearch(models.Model):  class SearchAltName(object):      def __init__( -            self, search_key, search_query, extra_query=None, distinct_query=False +            self, search_key, search_query, extra_query=None, distinct_query=False, related_name=None      ):          self.search_key = search_key          self.search_query = search_query          self.extra_query = extra_query or {}          self.distinct_query = distinct_query +        self.related_name = related_name  class Imported(models.Model): 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)  | 
