diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-04-28 11:21:45 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-04-28 11:24:37 +0200 |
commit | 380d95bb09f99d4da590010436d9d6bdd352f940 (patch) | |
tree | 27b5941fde7db58fccb6af62f998a0ca80a7fe25 | |
parent | 54d67899a220b29fd96652e34a40c6a6749ea8e2 (diff) | |
download | Ishtar-380d95bb09f99d4da590010436d9d6bdd352f940.tar.bz2 Ishtar-380d95bb09f99d4da590010436d9d6bdd352f940.zip |
Container autocomplete: unaccent - any order of container types
-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(): |