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) | 
