From 89f6e3656bcb569916f9d058b0d01dbf4ae5d9f5 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Thu, 3 Jan 2019 17:34:14 +0100 Subject: [PATCH] Show short entries first in search results to improve UX --- api/funkwhale_api/common/utils.py | 10 +++++++++- api/funkwhale_api/music/views.py | 17 +++++++++-------- changes/changelog.d/searchorder.enhancement | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 changes/changelog.d/searchorder.enhancement diff --git a/api/funkwhale_api/common/utils.py b/api/funkwhale_api/common/utils.py index 81bc5c026..bd9fd87c5 100644 --- a/api/funkwhale_api/common/utils.py +++ b/api/funkwhale_api/common/utils.py @@ -9,7 +9,7 @@ from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit from django.conf import settings from django import urls -from django.db import transaction +from django.db import models, transaction def rename_file(instance, field_name, new_name, allow_missing_file=False): @@ -139,3 +139,11 @@ def parse_meta(html): meta = [elem for elem in tree.iter() if elem.tag in ["meta", "link"]] return [dict([("tag", elem.tag)] + list(elem.items())) for elem in meta] + + +def order_for_search(qs, field): + """ + When searching, it's often more useful to have short results first, + this function will order the given qs based on the length of the given field + """ + return qs.annotate(__size=models.functions.Length(field)).order_by("__size") diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index 1fcd782fb..ba4ffd1f0 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -448,28 +448,29 @@ class Search(views.APIView): "artist__name__unaccent", ] query_obj = utils.get_query(query, search_fields) - return ( + qs = ( models.Track.objects.all() .filter(query_obj) .select_related("artist", "album__artist") - )[: self.max_results] + ) + return common_utils.order_for_search(qs, "title")[: self.max_results] def get_albums(self, query): search_fields = ["mbid", "title__unaccent", "artist__name__unaccent"] query_obj = utils.get_query(query, search_fields) - return ( + qs = ( models.Album.objects.all() .filter(query_obj) .select_related() - .prefetch_related("tracks") - )[: self.max_results] + .prefetch_related("tracks__artist") + ) + return common_utils.order_for_search(qs, "title")[: self.max_results] def get_artists(self, query): search_fields = ["mbid", "name__unaccent"] query_obj = utils.get_query(query, search_fields) - return (models.Artist.objects.all().filter(query_obj).with_albums())[ - : self.max_results - ] + qs = models.Artist.objects.all().filter(query_obj).with_albums() + return common_utils.order_for_search(qs, "name")[: self.max_results] def get_tags(self, query): search_fields = ["slug", "name__unaccent"] diff --git a/changes/changelog.d/searchorder.enhancement b/changes/changelog.d/searchorder.enhancement new file mode 100644 index 000000000..b180006a3 --- /dev/null +++ b/changes/changelog.d/searchorder.enhancement @@ -0,0 +1 @@ +Show short entries first in search results to improve UX