diff options
Diffstat (limited to 'ishtar_common/views_item.py')
-rw-r--r-- | ishtar_common/views_item.py | 113 |
1 files changed, 80 insertions, 33 deletions
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 8af79c6fa..437bbd651 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -32,7 +32,7 @@ from weasyprint.fonts import FontConfiguration from ishtar_common.utils import check_model_access_control, CSV_OPTIONS, \ get_all_field_names from ishtar_common.models import HistoryError, get_current_profile, \ - PRIVATE_FIELDS, GeneralType + PRIVATE_FIELDS, GeneralType, SearchAltName from menus import Menu import models @@ -381,21 +381,23 @@ FORBIDDEN_CHAR = [u":"] RESERVED_CHAR = [u"|", u"&"] -def _parse_query_string(string, request_keys, current_dct, exc_dct): +def _parse_query_string(string, query_parameters, current_dct, exc_dct, + extra_distinct_q): string = string.strip().lower() if u"=" in string: splited = string.split(u"=") if len(splited) == 2: - term, query = splited - excluded = term.startswith(u"-") + base_term, query = splited + excluded = base_term.startswith(u"-") if excluded: - term = term[1:] - if term in request_keys: + base_term = base_term[1:] + if base_term in query_parameters: dct = current_dct - term = request_keys[term] + 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 @@ -411,12 +413,26 @@ def _parse_query_string(string, request_keys, current_dct, exc_dct): if cextra: dct['extras'].append(cextra) else: - if excluded: + 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 + 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"") @@ -436,21 +452,24 @@ def _parse_query_string(string, request_keys, current_dct, exc_dct): return string -def _parse_parentheses_groups(groups, request_keys, current_dct=None, - exc_dct=None): +def _parse_parentheses_groups(groups, query_parameters, current_dct=None, + exc_dct=None, extra_distinct_q=None): """ Transform parentheses groups to query :param groups: groups to transform (list) - :param request_keys: request keys for facet search + :param query_parameters: query keys for facet search :param current_dct: query dict :param exc_dct: exclude query dict + :param exc_dct: exclude query dict :return: query string, query dict, excluded query dict """ if not current_dct: current_dct = {} if not exc_dct: exc_dct = {} + if not extra_distinct_q: + extra_distinct_q = [] if type(groups) is not list: string = groups.strip() if string.startswith(u'"') and string.endswith(u'"') and \ @@ -479,17 +498,19 @@ def _parse_parentheses_groups(groups, request_keys, current_dct=None, string_groups = [gp.replace(SEP, u" ") for gp in string.split(u" ")] if len(string_groups) == 1: return _parse_query_string( - string_groups[0], request_keys, current_dct, exc_dct), \ - current_dct, exc_dct - return _parse_parentheses_groups(string_groups, - request_keys, current_dct, exc_dct) + string_groups[0], query_parameters, current_dct, exc_dct, + extra_distinct_q + ), current_dct, exc_dct, extra_distinct_q + return _parse_parentheses_groups( + string_groups, query_parameters, current_dct, exc_dct, + extra_distinct_q) if not groups: # empty list - return "", current_dct, exc_dct + return "", current_dct, exc_dct, extra_distinct_q query = u"(" previous_sep, has_item = None, False for item in groups: - q, current_dct, exc_dct = _parse_parentheses_groups( - item, request_keys, current_dct, exc_dct) + q, current_dct, exc_dct, extra_distinct_q = _parse_parentheses_groups( + item, query_parameters, current_dct, exc_dct, extra_distinct_q) q = q.strip() if not q: continue @@ -509,18 +530,20 @@ def _parse_parentheses_groups(groups, request_keys, current_dct=None, query += u")" if query == u"()": query = u"" - return unidecode(query), current_dct, exc_dct + return unidecode(query), current_dct, exc_dct, extra_distinct_q -def _search_manage_search_vector(model, dct, exc_dct, request_keys): +def _search_manage_search_vector(model, dct, exc_dct, distinct_queries, + query_parameters): if 'search_vector' not in dct: - return dct, exc_dct + return dct, exc_dct, distinct_queries search_vector = dct['search_vector'] parentheses_groups = _parse_parentheses(search_vector) - search_query, extra_dct, extra_exc_dct = _parse_parentheses_groups( - parentheses_groups, request_keys) + search_query, extra_dct, extra_exc_dct, extra_distinct_q = \ + _parse_parentheses_groups(parentheses_groups, query_parameters) dct.update(extra_dct) + distinct_queries += extra_distinct_q exc_dct.update(extra_exc_dct) if search_query: @@ -536,7 +559,7 @@ def _search_manage_search_vector(model, dct, exc_dct, request_keys): 'params': [settings.ISHTAR_SEARCH_LANGUAGE, search_query]} ) - return dct, exc_dct + return dct, exc_dct, distinct_queries def _manage_bool_fields(model, bool_fields, reversed_bool_fields, dct, or_reqs): @@ -1033,11 +1056,18 @@ def get_item(model, func_name, default_name, extra_request_keys=None, else: query_own = model.get_query_owns(q.all()[0]) + query_parameters = {} + + if hasattr(model, 'get_query_parameters'): + query_parameters = model.get_query_parameters() + # get defaults from model - if not extra_request_keys and hasattr(model, 'EXTRA_REQUEST_KEYS'): + if not extra_request_keys and query_parameters: my_extra_request_keys = copy(model.EXTRA_REQUEST_KEYS) + for key in query_parameters: + my_extra_request_keys[key] = query_parameters[key].search_query else: - my_extra_request_keys = copy(extra_request_keys or []) + my_extra_request_keys = copy(extra_request_keys or {}) if base_request is None and hasattr(model, 'BASE_REQUEST'): if callable(model.BASE_REQUEST): my_base_request = model.BASE_REQUEST(request) @@ -1139,6 +1169,7 @@ def get_item(model, func_name, default_name, extra_request_keys=None, excluded_dct = {} and_reqs, or_reqs = [], [] exc_and_reqs, exc_or_reqs = [], [] + distinct_queries = [] dct['extras'], dct['and_reqs'], dct['exc_and_reqs'] = [], [], [] if full == 'shortcut': @@ -1158,11 +1189,19 @@ def get_item(model, func_name, default_name, extra_request_keys=None, if not val: continue req_keys = request_keys[k] + target = dct + if k in query_parameters: + if query_parameters[k].distinct_query: + distinct_queries.append({}) + target = distinct_queries[-1] + if query_parameters[k].extra_query: + target.update(query_parameters[k].extra_query) + if callable(req_keys): # callable request key for complex queries not managed on GET continue elif type(req_keys) not in (list, tuple): - dct[req_keys] = val + target[req_keys] = val continue # multiple choice target reqs = Q(**{req_keys[0]: val}) @@ -1184,8 +1223,14 @@ def get_item(model, func_name, default_name, extra_request_keys=None, else: request.session[func_name] = dct - dct, excluded_dct = _search_manage_search_vector( - model, dct, excluded_dct, request_keys) + for k in request_keys: + if k not in query_parameters: + query_parameters[k] = SearchAltName(k, request_keys[k]) + + dct, excluded_dct, distinct_queries = _search_manage_search_vector( + model, dct, excluded_dct, distinct_queries, query_parameters, + ) + search_vector = "" if 'search_vector' in dct: search_vector = dct.pop('search_vector') @@ -1254,9 +1299,12 @@ def get_item(model, func_name, default_name, extra_request_keys=None, if current: dct = {upper_key: current} query &= Q(**dct) - # print(query) items = model.objects.filter(query) + for d_q in distinct_queries: + print(d_q) + items = items.filter(d_q) + if base_query: items = items.filter(base_query) if exc_query: @@ -1422,9 +1470,8 @@ def get_item(model, func_name, default_name, extra_request_keys=None, keys = [keys] my_vals = [] for k in keys: - if hasattr(model, 'EXTRA_REQUEST_KEYS') \ - and k in model.EXTRA_REQUEST_KEYS: - k = model.EXTRA_REQUEST_KEYS[k] + if k in my_extra_request_keys: + k = my_extra_request_keys[k] if type(k) in (list, tuple): k = k[0] for filtr in ('__icontains', '__contains', '__iexact', |