diff options
Diffstat (limited to 'archaeological_warehouse/views.py')
| -rw-r--r-- | archaeological_warehouse/views.py | 61 | 
1 files changed, 33 insertions, 28 deletions
| 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 | 
