summaryrefslogtreecommitdiff
path: root/archaeological_warehouse
diff options
context:
space:
mode:
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
commit380d95bb09f99d4da590010436d9d6bdd352f940 (patch)
tree27b5941fde7db58fccb6af62f998a0ca80a7fe25 /archaeological_warehouse
parent54d67899a220b29fd96652e34a40c6a6749ea8e2 (diff)
downloadIshtar-380d95bb09f99d4da590010436d9d6bdd352f940.tar.bz2
Ishtar-380d95bb09f99d4da590010436d9d6bdd352f940.zip
Container autocomplete: unaccent - any order of container types
Diffstat (limited to 'archaeological_warehouse')
-rw-r--r--archaeological_warehouse/tests.py15
-rw-r--r--archaeological_warehouse/views.py61
2 files changed, 48 insertions, 28 deletions
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