summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2019-03-21 14:05:12 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2019-04-24 19:41:37 +0200
commit9fb6d3361809989ffab27b4e0ba4d31459c8bfb3 (patch)
treea255dd1b092e7e73bf5a097eb9f3cb03eece197b /ishtar_common
parent97ca6b195c509635a71a1bd1d15c0f24592e714d (diff)
downloadIshtar-9fb6d3361809989ffab27b4e0ba4d31459c8bfb3.tar.bz2
Ishtar-9fb6d3361809989ffab27b4e0ba4d31459c8bfb3.zip
Facet search: fix many values management
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/views_item.py101
1 files changed, 54 insertions, 47 deletions
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index ca75bffe1..d53498fae 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -390,7 +390,7 @@ def _parse_parentheses(s):
FORBIDDEN_CHAR = [u":"]
RESERVED_CHAR = [u"|", u"&"]
-RE_FACET = re.compile('([-a-zA-Z]+)="([^"]+)"')
+RE_FACET = re.compile('([-a-zA-Z]+)="([^"]+)"(?:;"([^"]+)")*')
def _parse_query_string(string, query_parameters, current_dct, exc_dct,
@@ -399,57 +399,65 @@ def _parse_query_string(string, query_parameters, current_dct, exc_dct,
match = RE_FACET.search(string)
if match or u"=" in string:
+ queries = []
if match:
- splited = match.groups()
+ for idx, gp in enumerate(match.groups()):
+ if not idx:
+ base_term = gp
+ elif gp:
+ queries.append(u'"{}"'.format(gp))
else:
splited = string.split(u"=")
- if len(splited) == 2:
- base_term, query = splited
+ if len(splited) == 2:
+ base_term = splited[0]
+ queries.append(splited[1])
+ if queries:
excluded = base_term.startswith(u"-")
if excluded:
base_term = base_term[1:]
if base_term in query_parameters:
dct = current_dct
term = query_parameters[base_term].search_query
- # callable request key for complex queries
- if callable(term):
- # !! distinct_queries not managed
- is_true = is_true_string(query)
- if excluded:
- is_true = not is_true
- cfltr, cexclude, cextra = term(is_true=is_true)
- if cfltr:
- if 'and_reqs' not in dct:
- dct['and_reqs'] = []
- dct['and_reqs'].append(cfltr)
- if cexclude:
- if 'exc_and_reqs' not in dct:
- dct['exc_and_reqs'] = []
- dct['exc_and_reqs'].append(cexclude)
- if cextra:
- dct['extras'].append(cextra)
- else:
- if query_parameters[base_term].distinct_query:
- extra_distinct_q.append({})
- dct = extra_distinct_q[-1]
- if not query_parameters[base_term].distinct_query and \
- excluded:
- dct = exc_dct
- if query_parameters[base_term].extra_query:
- dct.update(query_parameters[base_term].extra_query)
- if term in dct:
- dct[term] += u";" + query
- else:
- dct[term] = query
- if query_parameters[base_term].distinct_query:
- for k in dct: # clean "
- dct[k] = dct[k].replace('"', '')
- # distinct query wait for a query
- _manage_clean_search_field(dct)
+ for query in queries:
+ # callable request key for complex queries
+ if callable(term):
+ # !! distinct_queries not managed
+ is_true = is_true_string(query)
if excluded:
- extra_distinct_q[-1] = ~Q(**dct)
+ is_true = not is_true
+ cfltr, cexclude, cextra = term(is_true=is_true)
+ if cfltr:
+ if 'and_reqs' not in dct:
+ dct['and_reqs'] = []
+ dct['and_reqs'].append(cfltr)
+ if cexclude:
+ if 'exc_and_reqs' not in dct:
+ dct['exc_and_reqs'] = []
+ dct['exc_and_reqs'].append(cexclude)
+ if cextra:
+ dct['extras'].append(cextra)
+ else:
+ if query_parameters[base_term].distinct_query:
+ extra_distinct_q.append({})
+ dct = extra_distinct_q[-1]
+ if not query_parameters[base_term].distinct_query and \
+ excluded:
+ dct = exc_dct
+ if query_parameters[base_term].extra_query:
+ dct.update(query_parameters[base_term].extra_query)
+ if term in dct:
+ dct[term] += u";" + query
else:
- extra_distinct_q[-1] = Q(**dct)
+ dct[term] = query
+ if query_parameters[base_term].distinct_query:
+ for k in dct: # clean "
+ dct[k] = dct[k].replace('"', '')
+ # distinct query wait for a query
+ _manage_clean_search_field(dct)
+ if excluded:
+ extra_distinct_q[-1] = ~Q(**dct)
+ else:
+ extra_distinct_q[-1] = Q(**dct)
return u""
for reserved_char in FORBIDDEN_CHAR:
string = string.replace(reserved_char, u"")
@@ -681,14 +689,14 @@ def _manage_facet_search(model, dct, and_reqs):
or not dct[k].startswith(u'"'):
continue
val = _clean_type_val(dct.pop(k))
- if u";" in val:
+ if u'";"' in val:
# OR request
values = val.split(u";")
else:
values = [val]
reqs = None
for val in values:
- if not val.endswith(u'"') or not val.startswith(u""):
+ if not val.endswith(u'"') or not val.startswith(u'"'):
continue
suffix = "__label__icontains" if u"%" in val else \
"__label__iexact"
@@ -785,7 +793,7 @@ def _manage_hierarchic_fields(dct, and_reqs):
or req.endswith(k_hr + '__label__iexact'):
val = _clean_type_val(dct.pop(req))
- if u";" in val:
+ if u'";"' in val:
# OR request
values = val.split(u";")
else:
@@ -801,15 +809,14 @@ def _manage_hierarchic_fields(dct, and_reqs):
for val in values:
suffix = base_suffix[:]
req = base_req[:]
-
- if val.startswith(u'"') and val.startswith(u'"'):
+ if val.endswith(u'"') and val.startswith(u'"'):
+ val = val[1:-1]
# manage search text by label
if u"*" in val:
suffix = "label__icontains"
val = val.replace(u'*', u"")
else:
suffix = "label__iexact"
- val = val[1:-1]
req = req[:-(len(base_suffix))] + suffix
if not reqs: