diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-12-03 00:00:34 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-12-03 00:00:34 +0100 |
commit | e7165c5915d5ecddf1248f0cbfb03e5efccd45a7 (patch) | |
tree | b6ea35231e2ee8406be9e6ee7b930b5180655c6b | |
parent | df84c1f2b6d7bf469e2a914e43a2f268c90cdd23 (diff) | |
download | Ishtar-e7165c5915d5ecddf1248f0cbfb03e5efccd45a7.tar.bz2 Ishtar-e7165c5915d5ecddf1248f0cbfb03e5efccd45a7.zip |
Search: manage complex queries - Find search: loan status
-rw-r--r-- | archaeological_finds/forms.py | 1 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 22 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 49 |
3 files changed, 63 insertions, 9 deletions
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index e42259bad..3019d4aa2 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -883,6 +883,7 @@ class FindSelect(HistorySelect): base_finds__batch = forms.ChoiceField( label=_(u"Batch/object"), choices=[]) checked_type = forms.ChoiceField(label=_("Check")) + loan = forms.NullBooleanField(label=_(u"Loan?")) documents__image__isnull = forms.NullBooleanField(label=_(u"Has an image?")) TYPES = [ diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index ee6253109..08fb15f0e 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -23,7 +23,7 @@ from django.conf import settings from django.contrib.gis.db import models from django.core.urlresolvers import reverse from django.db import connection -from django.db.models import Max, Q +from django.db.models import Max, Q, F from django.db.models.signals import m2m_changed, post_save, post_delete, \ pre_delete from django.core.exceptions import ObjectDoesNotExist @@ -668,6 +668,20 @@ class FBulkView(object): """ +def query_loan(is_true=True): + """ + Query to get loan find + + :return: (filter, exclude, extra) + """ + if is_true: + return Q(container_ref__isnull=False, container__isnull=False), \ + Q(container_ref=F('container')), None + else: + return Q(container_ref__isnull=False, container__isnull=False, + container_ref=F('container')), None, None + + class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, MainItem): EXTERNAL_ID_KEY = 'find_external_id' @@ -954,6 +968,10 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, pgettext_lazy("key for text search", u"created-by"), 'history_creator__ishtaruser__person__cached_label__iexact' ), + 'loan': ( + pgettext_lazy("key for text search", u"loan"), + query_loan + ) } for v in ALT_NAMES.values(): for language_code, language_lbl in settings.LANGUAGES: @@ -961,6 +979,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] deactivate() + EXTRA_REQUEST_FUNC = {""} + PARENT_SEARCH_VECTORS = ['base_finds'] BASE_SEARCH_VECTORS = [ "cached_label", "label", "description", "container__location__name", diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 2d8b6b828..85db87605 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -339,6 +339,12 @@ def _push_to_list(obj, current_group, depth): current_group.append(obj) +def is_true_string(val): + val = unicode(val).lower().replace(u'"', u"") + if val in (u"1", u"true", unicode(_(u"True")).lower()): + return True + + def _parse_parentheses(s): """ Parse parentheses into list. @@ -382,14 +388,31 @@ def _parse_query_string(string, request_keys, current_dct, exc_dct): if excluded: term = term[1:] if term in request_keys: - term = request_keys[term] dct = current_dct - if excluded: - dct = exc_dct - if term in dct: - dct[term] += u";" + query + term = request_keys[term] + # callable request key for complex queries + if callable(term): + 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: - dct[term] = query + if excluded: + dct = exc_dct + if term in dct: + dct[term] += u";" + query + else: + dct[term] = query return u"" for reserved_char in FORBIDDEN_CHAR: string = string.replace(reserved_char, u"") @@ -809,7 +832,12 @@ def _construct_query(relation_types, dct, or_reqs, and_reqs): query |= Q(**alt_dct) query = _manage_relation_types(relation_types, dct, query, or_reqs) + done = [] for and_req in and_reqs: + str_q = unicode(and_req) + if str_q in done: + continue + done.append(str_q) query = query & and_req return query @@ -1068,6 +1096,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 = [], [] + dct['extras'], dct['and_reqs'], dct['exc_and_reqs'] = [], [], [] if full == 'shortcut': if model.SLUG == "warehouse": @@ -1086,7 +1115,10 @@ def get_item(model, func_name, default_name, extra_request_keys=None, if not val: continue req_keys = request_keys[k] - if type(req_keys) not in (list, tuple): + 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 continue # multiple choice target @@ -1109,7 +1141,6 @@ def get_item(model, func_name, default_name, extra_request_keys=None, else: request.session[func_name] = dct - dct['extras'] = [] dct, excluded_dct = _search_manage_search_vector( model, dct, excluded_dct, request_keys) search_vector = "" @@ -1146,6 +1177,8 @@ def get_item(model, func_name, default_name, extra_request_keys=None, _manage_facet_search(model, excluded_dct, exc_and_reqs) extras = dct.pop('extras') + and_reqs += dct.pop('and_reqs') + exc_and_reqs += dct.pop('exc_and_reqs') _manage_clean_search_field(dct) _manage_clean_search_field(excluded_dct) |