fixup: order users autocomplete by username length

cf #2591
This commit is contained in:
Yohan Boniface 2025-04-08 15:47:06 +02:00
parent f4ae51ae7e
commit 14663bc56e
2 changed files with 12 additions and 22 deletions

View file

@ -2,7 +2,7 @@ from agnocomplete.core import AgnocompleteModel
from agnocomplete.register import register from agnocomplete.register import register
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db.models import Q from django.db.models.functions import Length
@register @register
@ -15,23 +15,10 @@ class AutocompleteUser(AgnocompleteModel):
data["url"] = current_item.get_url() data["url"] = current_item.get_url()
return data return data
def get_queryset_filters(self, query): def build_extra_filtered_queryset(self, queryset, **kwargs):
if len(query) <= 3 and self._force_exact: order_by = []
conditions = Q()
for field_name in self.fields: for field_name in self.fields:
if not field_name[0].isalnum(): if not field_name[0].isalnum():
field_name = field_name[1:] field_name = field_name[1:]
# Force exact match order_by.append(Length(field_name).asc())
conditions |= Q(**{self._construct_qs_filter(f"={field_name}"): query}) return queryset.order_by(*order_by)
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

View file

@ -516,10 +516,13 @@ def test_can_combine_search_and_filter(client, map):
def test_can_find_small_usernames(client): def test_can_find_small_usernames(client):
UserFactory(username="Joe") UserFactory(username="Joe")
UserFactory(username="JoeJoe") UserFactory(username="JoeJoe")
UserFactory(username="Joe3")
UserFactory(username="Joe57")
UserFactory(username="JoeBar")
url = "/agnocomplete/AutocompleteUser/" url = "/agnocomplete/AutocompleteUser/"
response = client.get(url + "?q=joe") response = client.get(url + "?q=joe")
data = json.loads(response.content)["data"] data = json.loads(response.content)["data"]
assert len(data) == 1 assert len(data) == 5
assert data[0]["label"] == "Joe" assert data[0]["label"] == "Joe"
response = client.get(url + "?q=joej") response = client.get(url + "?q=joej")
data = json.loads(response.content)["data"] data = json.loads(response.content)["data"]