diff options
| -rw-r--r-- | CHANGES.md | 6 | ||||
| -rw-r--r-- | archaeological_warehouse/tests.py | 15 | ||||
| -rw-r--r-- | archaeological_warehouse/views.py | 61 | ||||
| -rw-r--r-- | ishtar_common/version.py | 4 | 
4 files changed, 56 insertions, 30 deletions
diff --git a/CHANGES.md b/CHANGES.md index a8465995d..5c5e304f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,12 @@  Ishtar changelog  ================ +v3.1.14 - 2021-04-28 +-------------------- + +### Features ### +- Better filter on container autocomplete - manage unaccent any order in parent +  v3.1.13 - 2021-04-20  -------------------- diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py index e18d56fae..347382e75 100644 --- a/archaeological_warehouse/tests.py +++ b/archaeological_warehouse/tests.py @@ -598,6 +598,21 @@ class ContainerTest(FindInit, TestCase):          self.assertEqual(response.status_code, 200)          c = json.loads(response.content.decode())          self.assertEqual(len(c), 1) +        # inverse position +        full_path = "{} 35000 {} Test".format(ct2.label, ct.label) +        response = client.get(url, {"term": full_path}) +        self.assertEqual(response.status_code, 200) +        c = json.loads(response.content.decode()) +        self.assertEqual(len(c), 1) +        # unaccent +        ct2_label = ct2.label +        assert "e" in ct2_label +        ct2_label = ct2_label.replace("e", "é") +        full_path = "{} 35000 {} Test".format(ct2_label, ct.label) +        response = client.get(url, {"term": full_path}) +        self.assertEqual(response.status_code, 200) +        c = json.loads(response.content.decode()) +        self.assertEqual(len(c), 1)      def test_form_creation(self):          data = { diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py index 4fa60ff89..c6072a4df 100644 --- a/archaeological_warehouse/views.py +++ b/archaeological_warehouse/views.py @@ -18,6 +18,7 @@  # See the file COPYING for details.  import json +from unidecode import unidecode  from django.core.urlresolvers import reverse  from django.db.models import Q @@ -143,33 +144,34 @@ def autocomplete_container(request, warehouse_id=None):      )      limit = 15 - len(containers)      splitted = [s.lower() for s in term.split(" ") if s and s != "|"] +    unaccent_splitted = [unidecode(s).lower() for s in term.split(" ") +                         if s and s != "|"]      if limit > 0 and len(splitted) > 1:          type_positions = []  # container_type ID, pos inf, pos sup          container_types = [ -            (c[0], c[1]) +            (c[0], unidecode(c[1]).lower())              for c in models.ContainerType.objects.values_list("id", "label")          ]          for container_type_id, value in container_types: -            if value.lower() in term.lower():  # container_type is in search q -                values = [v.lower() for v in value.split(" ") if v] - +            if value in unidecode(term).lower():  # container_type is in search q +                values = [unidecode(v.lower()) for v in value.split(" ") if v]                  # verify that all term match in splitted                  try: -                    index = splitted.index(values[0].lower()) +                    index = unaccent_splitted.index(values[0])                  except ValueError:                      index = None                  index_is_ok = False                  while not index_is_ok and index is not None:                      for idx, v in enumerate(values):                          try: -                            assert splitted[index + idx] == v +                            assert unaccent_splitted[index + idx] == v                          except (ValueError, AssertionError):                              break                          index_is_ok = True                      if not index_is_ok:                          try: -                            index = splitted.index(values[0].lower(), index + 1) +                            index = unaccent_splitted.index(values[0], index + 1)                          except ValueError:                              index = None                  if index_is_ok: @@ -182,27 +184,30 @@ def autocomplete_container(request, warehouse_id=None):              for idx in range(type_positions[0][1]):                  query &= Q(location__name__icontains=splitted[idx])          # group by container type, ref tuple -        groups = [] -        for idx, (container_type_id, pos_inf, pos_sup) in enumerate(type_positions): -            if len(type_positions) == idx + 1:  # last -                value = " ".join(splitted[pos_sup:]) -            else: -                value = " ".join(splitted[pos_sup : type_positions[idx + 1][1]]) -            if value: -                groups.append((container_type_id, value)) -        if groups: -            query = base_query -            for idx, g in enumerate(reversed(groups)): -                base_key = "parent__" * idx -                key1 = base_key + "container_type_id" -                key2 = base_key + "reference__unaccent__iexact" -                query &= Q(**{key1: g[0], key2: g[1]}) -            ids = {c["id"] for c in containers} -            containers += list( -                models.Container.objects.filter(query) -                .exclude(pk__in=ids) -                .values("id", "cached_label")[:limit] -            ) +        # can be in any order +        for positions in (type_positions, list(reversed(type_positions))): +            groups = [] +            for idx, (container_type_id, pos_inf, pos_sup) in enumerate(positions): +                if len(positions) == idx + 1:  # last +                    value = " ".join(splitted[pos_sup:]) +                else: +                    value = " ".join(splitted[pos_sup:positions[idx + 1][1]]) +                if value: +                    groups.append((container_type_id, value)) +            if groups: +                for gp in (groups, reversed(groups)): +                    query = base_query +                    for idx, g in enumerate(gp): +                        base_key = "parent__" * idx +                        key1 = base_key + "container_type_id" +                        key2 = base_key + "reference__unaccent__iexact" +                        query &= Q(**{key1: g[0], key2: g[1]}) +                    ids = {c["id"] for c in containers} +                    containers += list( +                        models.Container.objects.filter(query) +                        .exclude(pk__in=ids) +                        .values("id", "cached_label")[:limit] +                    )      if len(splitted) > 1 and len(containers) < 15:          # group to do a "type" "reference" search diff --git a/ishtar_common/version.py b/ishtar_common/version.py index e9e97234e..cee8b8d69 100644 --- a/ishtar_common/version.py +++ b/ishtar_common/version.py @@ -1,5 +1,5 @@ -# 3.1.13 -VERSION = (3, 1, 13) +# 3.1.14 +VERSION = (3, 1, 14)  def get_version():  | 
