diff options
-rw-r--r-- | archaeological_context_records/models.py | 1 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 1 | ||||
-rw-r--r-- | archaeological_finds/tests.py | 29 | ||||
-rw-r--r-- | archaeological_operations/models.py | 1 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 74 |
5 files changed, 98 insertions, 8 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 940b7347f..1e5d108bc 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -564,6 +564,7 @@ class ContextRecord( "documents__associated_file__isnull", "documents__associated_url__isnull", ] + NUMBER_FIELDS = ["operation__year"] RELATION_TYPES_PREFIX = { "ope_relation_types": "operation__", "cr_relation_types": "", diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index fff692917..7a8715f1b 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1259,6 +1259,7 @@ class Find( "museum_allocation_date__lte", "museum_allocation_date__gte", ] + NUMBER_FIELDS = ["base_finds__context_record__operation__year"] BASE_REQUEST = {"downstream_treatment__isnull": True} EXTRA_REQUEST_KEYS = { "all_base_finds__context_record": "base_finds__context_record__context_record_tree_parent__cr_parent_id", diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py index 60dcb5a5d..346aa0b1e 100644 --- a/archaeological_finds/tests.py +++ b/archaeological_finds/tests.py @@ -1591,6 +1591,35 @@ class FindSearchTest(FindInit, TestCase, SearchText): result = [('-{}="{}"'.format(key, "*"), models.Find.objects.count() - 1)] self._test_search(c, result, context="-* description Search") + def test_number_search(self): + # test year search with "=>" notation + ope1 = self.operations[0] + ope1.year = 2000 + ope1.save() + ope2 = self.operations[1] + ope2.year = 2020 + ope2.save() + self.create_finds() + self.create_finds() + + c = Client() + c.login(username=self.username, password=self.password) + + key = str(pgettext_lazy("key for text search", "year")) + + result = [('{}="{}"'.format(key, 2000), 3)] + self._test_search(c, result, context="Exact year search") + result = [('{}="{}"'.format(key, 2020), 1)] + self._test_search(c, result, context="Exact year search") + result = [('{}=>"{}"'.format(key, 2019), 1)] + self._test_search(c, result, context="=> year search") + result = [('{}=>"{}"'.format(key, 1999), 4)] + self._test_search(c, result, context="=> year search") + result = [('{}=<"{}"'.format(key, 2001), 3)] + self._test_search(c, result, context="=< year search") + result = [('{}=>"{}" {}=<"{}"'.format(key, 2001, key, 2022), 1)] + self._test_search(c, result, context="=> and =< year search") + def test_address_operation_search(self): operation = self.operations[0] operation.address = "Street somewhere 29478 NOWHERE" diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 760ce1b4b..9764b8dba 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -1025,6 +1025,7 @@ class Operation( "finds_deadline__gte", "finds_deposit_date", ] + NUMBER_FIELDS = ["year", "operation_code"] EXTRA_REQUEST_KEYS = { "operation_type__label": "operation_type__label", "common_name": "common_name__icontains", diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 9f2fbb7b5..a622fdb9f 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -976,6 +976,67 @@ def _manage_many_counted_fields(fields, reversed_fields, dct, excluded_dct): excluded_dct[k] = False +def __manage_relative_search(value): + """ + Parse search to manage "=", "=>" and "=<" searches + :param value: value + :return: value, search type ("eq", "lte" or "gte") + """ + value = value.replace('"', "").strip() + search_type = "eq" + if value.startswith(">"): + value = value[1:] + search_type = "gte" + elif value.startswith("<"): + value = value[1:] + search_type = "lte" + return value, search_type + + +def _manage_number(k, dct): + """ + Manage number from a search query + :param k: number key + :param dct: search dict + :return: None -> search dict is modified + """ + values = dct[k].split(";") + results = [] + for value in values: + value, search_type = __manage_relative_search(value) + try: + value = str(float(value.replace(",", "."))) + if value.endswith(".0"): + value = value[:-2] + results.append((search_type, value)) + except ValueError: + continue + mins = [value for dt, value in results if dt == "gte"] + maxs = [value for dt, value in results if dt == "lte"] + eqs = [value for dt, value in results if dt == "eq"] + if eqs and not mins and not maxs: # TODO: min and max not available + dct[k] = ";".join(eqs) + return + dct.pop(k) + if mins: + dct[k + "__gte"] = min(mins) + if maxs: + dct[k + "__lte"] = max(maxs) + + +def _manage_number_fields(fields, dct): + keys = list(dct.keys()) + for key in fields: + res = [j for j in keys if j.startswith(key)] + if not res: + continue + for k in res: + if not dct[k]: + dct.pop(k) + continue + _manage_number(k, dct) + + today_lbl = pgettext_lazy("key for text search", "today") TODAYS = ["today"] @@ -995,14 +1056,7 @@ def _manage_date(k, dct): values = dct[k].split(";") results = [] for value in values: - value = value.replace('"', "").strip() - date_type = "eq" - if value.startswith(">"): - value = value[1:] - date_type = "gte" - elif value.startswith("<"): - value = value[1:] - date_type = "lte" + value, date_type = __manage_relative_search(value) has_today = False for today in TODAYS: if value.startswith(today): @@ -2020,6 +2074,7 @@ def get_item( reversed_many_counted_fields = getattr( model, "REVERSED_MANY_COUNTED_FIELDS", None ) + my_number_fields = getattr(model, "NUMBER_FIELDS", [])[:] if not dated_fields and hasattr(model, "DATED_FIELDS"): my_dated_fields = model.DATED_FIELDS[:] @@ -2295,6 +2350,9 @@ def get_item( _manage_dated_fields(my_dated_fields, dct) _manage_dated_fields(my_dated_fields, excluded_dct) + _manage_number_fields(my_number_fields, dct) + _manage_number_fields(my_number_fields, excluded_dct) + _manage_hierarchic_fields(model, dct, and_reqs) _manage_hierarchic_fields(model, excluded_dct, exc_and_reqs) |