diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-02-12 11:36:21 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-02-28 12:15:24 +0100 |
commit | 5683f1ef9128367e8bcbe87eb58a122a9e7e1aea (patch) | |
tree | 5f4779b7e1b91b0f86376591dbe087bf38306021 /archaeological_warehouse | |
parent | 6b51ad99e8787d33fba8d22f32517ec8be8414db (diff) | |
download | Ishtar-5683f1ef9128367e8bcbe87eb58a122a9e7e1aea.tar.bz2 Ishtar-5683f1ef9128367e8bcbe87eb58a122a9e7e1aea.zip |
Container autocomplete: improve search
Diffstat (limited to 'archaeological_warehouse')
-rw-r--r-- | archaeological_warehouse/tests.py | 43 | ||||
-rw-r--r-- | archaeological_warehouse/views.py | 30 |
2 files changed, 69 insertions, 4 deletions
diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py index 93acafa9f..873941d8e 100644 --- a/archaeological_warehouse/tests.py +++ b/archaeological_warehouse/tests.py @@ -513,6 +513,49 @@ class ContainerTest(FindInit, TestCase): warehouse_type=models.WarehouseType.objects.all()[0] ) + def test_container_search(self): + ct = models.ContainerType.objects.all()[0] + ct2 = models.ContainerType.objects.all()[0] + container_1 = models.Container.objects.create( + reference="Test", responsible=self.main_warehouse, + location=self.main_warehouse, + container_type=ct + ) + container_2 = models.Container.objects.create( + reference="35000", responsible=self.main_warehouse, + parent=container_1, + location=self.main_warehouse, + container_type=ct2 + ) + container_2.index = 42000 + container_2.save() + username, password, user = create_user() + user.user_permissions.add(Permission.objects.get( + codename='view_warehouse')) + client = Client() + client.login(username=username, password=password) + url = "/autocomplete-container/{}/".format(self.main_warehouse.pk) + response = client.get(url, {"term": "Test"}) + self.assertEqual(response.status_code, 200) + c = json.loads(response.content.decode()) + self.assertEqual(len(c), 2) + response = client.get(url, {"term": "Test 35000"}) + self.assertEqual(response.status_code, 200) + c = json.loads(response.content.decode()) + self.assertEqual(len(c), 1) + response = client.get(url, {"term": "42000"}) + self.assertEqual(response.status_code, 200) + c = json.loads(response.content.decode()) + self.assertEqual(len(c), 1) + response = client.get( + url, + {"term": "{} Test {} Test 35000".format(ct.label, ct2.label)}) + self.assertEqual(response.status_code, 200) + c = json.loads(response.content.decode()) + self.assertEqual(len(c), 1) + + + def test_form_creation(self): data = { 'reference': 'hop-ref', diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py index bc8bac127..efa5bdf19 100644 --- a/archaeological_warehouse/views.py +++ b/archaeological_warehouse/views.py @@ -95,20 +95,42 @@ def autocomplete_container(request, warehouse_id=None): return HttpResponse(content_type='text/plain') if not request.GET.get('term'): return HttpResponse(content_type='text/plain') - term = request.GET.get('term') + term = request.GET.get('term').strip() limit = 15 base_query = Q() if warehouse_id: base_query = Q(location_id=warehouse_id) query = base_query + # exact index + try: + query = query & Q(index=int(term)) + containers = list(models.Container.objects.filter( + query).values('id', 'cached_label')[:limit]) + except ValueError: + containers = [] # exact ref query = query & Q(reference__unaccent__iexact=term) - containers = list(models.Container.objects.filter( + containers += list(models.Container.objects.filter( query).values('id', 'cached_label')[:limit]) limit = 15 - len(containers) - splitted = term.split(' ') + splitted = [s for s in term.split(' ') if s] if limit > 0: - if len(splitted) > 1: + if len(splitted) > 1 and not len(splitted) % 2: + # group by container type, ref tuple + groups = [(splitted[idx * 2], splitted[idx * 2 + 1]) + for idx in range(int(len(splitted) / 2))] + query = base_query + for idx, g in enumerate(reversed(groups)): + base_key = "parent__" * idx + key1 = base_key + "container_type__label__unaccent__iexact" + key2 = base_key + "reference__unaccent__iexact" + query &= Q(**{key1: g[0], key2: g[1]}) + ids = set([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 (15 - len(containers)) > 0: # group to do a "type" "reference" search for idx in range(1, len(splitted)): group_1 = splitted[:idx] |