diff options
Diffstat (limited to 'ishtar_common/views_item.py')
| -rw-r--r-- | ishtar_common/views_item.py | 159 | 
1 files changed, 107 insertions, 52 deletions
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index cecc0318d..5d2c92899 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -1306,6 +1306,104 @@ def _manage_facet_search(model, dct, and_reqs):              dct[k] = getattr(model, POST_PROCESS_REQUEST[k])(dct[k].replace('"', "")) +def _manage_hierarchic_precise_town(req, dct, and_reqs): +    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(";")] +    town_ids = [] +    Town = apps.get_model("ishtar_common", "Town") +    for val in vals: +        q = Town.objects.filter(cached_label__iexact=val).values_list( +            "id", flat=True) +        if not q.count(): +            continue +        town_id = q.all()[0] +        town_ids.append(town_id) +        for rel_query in ("parents__", "children__"): +            for idx in range(HIERARCHIC_LEVELS): +                k = rel_query * (idx + 1) + "pk" +                q = Town.objects.filter( +                    **{k: town_id}).values_list("id", flat=True) +                if not q.count(): +                    break +                town_ids += list(q.all()) +    main_req = Q(**{req + "__in": town_ids}) +    and_reqs.append(main_req) + + +def _manage_hierarchic_precise_town_area(req, dct, and_reqs): +    if req.endswith("pk"): +        suffix = "pk" +    elif req.endswith("label__iexact"): +        suffix = "label__iexact" +    else: +        return +    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", "" +        ).replace("precise_town__areas", "precise_town_id")  # * -> is attached to a town +        req += "isnull" +        reqs = Q(**{req: False}) +        and_reqs.append(reqs) +        return +    elif "*" in val and "iexact" in suffix: +        suffix = suffix.replace("iexact", "icontains") +        req = req.replace("iexact", "icontains") +        val = val.replace("*", "") +    Town = apps.get_model("ishtar_common", "Town") +    Area = apps.get_model("ishtar_common", "Area") +    q_area = Area.objects.filter(**{suffix: val}) +    q_towns = Town.objects.filter(areas__pk__in=q_area.values_list("pk", flat=True)) +    req = req.replace("precise_town__areas__label__iexact", "precise_town_id__in") +    val_towns = q_towns.values_list("pk", flat=True) +    reqs = Q(**{req: val_towns}) + +    for idx in range(HIERARCHIC_LEVELS): +        suffix = "parent__" + suffix +        q_area = Area.objects.filter(**{suffix: val}) +        q_towns = Town.objects.filter(areas__pk__in=q_area.values_list("pk", flat=True)) +        if q_towns.count(): +            val_towns = q_towns.values_list("pk", flat=True) +            q = Q(**{req: val_towns}) +            reqs |= q +    and_reqs.append(reqs) + + +def _manage_hierarchic_area(req, dct, and_reqs): +    if req.endswith("pk"): +        suffix = "pk" +    elif req.endswith("label__iexact"): +        suffix = "label__iexact" +    else: +        return +    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) +        return +    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): +        req = req[: -(len(suffix))] + "parent__" + suffix +        q = Q(**{req: val}) +        reqs |= q +    and_reqs.append(reqs) +    # TODO: improve query with "IN ()"? + +  def _manage_hierarchic_fields(model, dct, and_reqs):      hierarchic_fields = HIERARCHIC_FIELDS[:]      if hasattr(model, "hierarchic_fields"): @@ -1315,35 +1413,13 @@ def _manage_hierarchic_fields(model, dct, and_reqs):          if type(reqs) not in (list, tuple):              reqs = [reqs]          for req in reqs: +            if req.endswith( +                    "precise_town__areas__label__iexact" +                    ) or req.endswith("precise_town__areas__pk"): +                _manage_hierarchic_precise_town_area(req, dct, and_reqs) +                continue              if req.endswith("areas__pk") or req.endswith("areas__label__iexact"): -                if req.endswith("pk"): -                    suffix = "pk" -                elif req.endswith("label__iexact"): -                    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): -                    req = req[: -(len(suffix))] + "parent__" + suffix -                    q = Q(**{req: val}) -                    reqs |= q -                and_reqs.append(reqs) -                # TODO: improve query with "IN ()"? +                _manage_hierarchic_area(req, dct, and_reqs)                  continue              if req.endswith("wcontainer_id") or req.endswith("wcontainer_ref_id"): @@ -1371,32 +1447,11 @@ def _manage_hierarchic_fields(model, dct, and_reqs):                      container_ids += list(q.all())                  main_req = Q(**{req + "__in": container_ids})                  and_reqs.append(main_req) +                continue              if req.endswith("precise_town_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(";")] -                town_ids = [] -                for val in vals: -                    q = Town.objects.filter(cached_label__iexact=val).values_list( -                        "id", flat=True) -                    if not q.count(): -                        continue -                    town_id = q.all()[0] -                    town_ids.append(town_id) -                    reqs = Q(**{req: val}) -                    for rel_query in ("parents__", "children__"): -                        for idx in range(HIERARCHIC_LEVELS): -                            k = rel_query * (idx + 1) + "pk" -                            q = Town.objects.filter( -                                **{k: town_id}).values_list("id", flat=True) -                            if not q.count(): -                                break -                            town_ids += list(q.all()) -                main_req = Q(**{req + "__in": town_ids}) -                and_reqs.append(main_req) - +                _manage_hierarchic_precise_town(req, dct, and_reqs) +                continue              elif (                  req.endswith("town__pk")                  or req.endswith("towns__pk")  | 
