diff --git a/umap/autocomplete.py b/umap/autocomplete.py index 537fa634..6a6fde14 100644 --- a/umap/autocomplete.py +++ b/umap/autocomplete.py @@ -2,7 +2,7 @@ from agnocomplete.core import AgnocompleteModel from agnocomplete.register import register from django.conf import settings from django.contrib.auth import get_user_model -from django.db.models import Q +from django.db.models.functions import Length @register @@ -15,23 +15,10 @@ class AutocompleteUser(AgnocompleteModel): data["url"] = current_item.get_url() return data - def get_queryset_filters(self, query): - if len(query) <= 3 and self._force_exact: - conditions = Q() - for field_name in self.fields: - if not field_name[0].isalnum(): - field_name = field_name[1:] - # Force exact match - conditions |= Q(**{self._construct_qs_filter(f"={field_name}"): query}) - return conditions - - return super().get_queryset_filters(query) - - def build_filtered_queryset(self, query, **kwargs): - self._force_exact = len(query) <= 3 - qs = super().build_filtered_queryset(query, **kwargs) - if len(query) <= 3 and not len(qs): - # Not exact match, let's fallback to normal "startswith" query - self._force_exact = False - qs = super().build_filtered_queryset(query, **kwargs) - return qs + def build_extra_filtered_queryset(self, queryset, **kwargs): + order_by = [] + for field_name in self.fields: + if not field_name[0].isalnum(): + field_name = field_name[1:] + order_by.append(Length(field_name).asc()) + return queryset.order_by(*order_by) diff --git a/umap/tests/test_views.py b/umap/tests/test_views.py index 9a963c61..9ecea639 100644 --- a/umap/tests/test_views.py +++ b/umap/tests/test_views.py @@ -516,10 +516,13 @@ def test_can_combine_search_and_filter(client, map): def test_can_find_small_usernames(client): UserFactory(username="Joe") UserFactory(username="JoeJoe") + UserFactory(username="Joe3") + UserFactory(username="Joe57") + UserFactory(username="JoeBar") url = "/agnocomplete/AutocompleteUser/" response = client.get(url + "?q=joe") data = json.loads(response.content)["data"] - assert len(data) == 1 + assert len(data) == 5 assert data[0]["label"] == "Joe" response = client.get(url + "?q=joej") data = json.loads(response.content)["data"]