summaryrefslogtreecommitdiff
path: root/ishtar_common/views_item.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/views_item.py')
-rw-r--r--ishtar_common/views_item.py159
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")