diff --git a/api/funkwhale_api/common/filters.py b/api/funkwhale_api/common/filters.py index 6fb4b1b45..65f5e008d 100644 --- a/api/funkwhale_api/common/filters.py +++ b/api/funkwhale_api/common/filters.py @@ -1,5 +1,6 @@ from django import forms from django.db.models import Q +from django.db.models.functions import Lower from django_filters import rest_framework as filters from django_filters import widgets from drf_spectacular.utils import extend_schema_field @@ -239,3 +240,19 @@ class ActorScopeFilter(filters.CharFilter): raise EmptyQuerySet() return Q(**{self.actor_field: actor}) + + +class CaseInsensitiveNameOrderingFilter(filters.OrderingFilter): + def filter(self, qs, value): + order_by = [] + + if value is None: + return qs + + for param in value: + if param == "name": + order_by.append(Lower("name")) + else: + order_by.append(self.get_ordering_value(param)) + + return qs.order_by(*order_by) diff --git a/api/funkwhale_api/music/filters.py b/api/funkwhale_api/music/filters.py index 0fc18bd8a..94fa15e14 100644 --- a/api/funkwhale_api/music/filters.py +++ b/api/funkwhale_api/music/filters.py @@ -104,7 +104,7 @@ class ArtistFilter( distinct=True, library_field="tracks__uploads__library", ) - ordering = django_filters.OrderingFilter( + ordering = common_filters.CaseInsensitiveNameOrderingFilter( fields=( ("id", "id"), ("name", "name"), diff --git a/api/tests/music/test_filters.py b/api/tests/music/test_filters.py index 4879b6f38..54fc60072 100644 --- a/api/tests/music/test_filters.py +++ b/api/tests/music/test_filters.py @@ -3,9 +3,32 @@ import pytest from funkwhale_api.music import filters, models +def test_artist_filter_ordering(factories, mocker): + # Lista de prueba + artist1 = factories["music.Artist"](name="Anita Muller") + artist2 = factories["music.Artist"](name="Jane Smith") + artist3 = factories["music.Artist"](name="Adam Johnson") + artist4 = factories["music.Artist"](name="anita iux") + + qs = models.Artist.objects.all() + + cf = factories["moderation.UserFilter"](for_artist=True) + + # Request con ordenamiento + filterset = filters.ArtistFilter( + {"ordering": "name"}, request=mocker.Mock(user=cf.user), queryset=qs + ) + + expected_order = [artist3.name, artist4.name, artist1.name, artist2.name] + actual_order = list(filterset.qs.values_list("name", flat=True)) + + assert actual_order == expected_order + + def test_album_filter_hidden(factories, mocker, queryset_equal_list): factories["music.Album"]() cf = factories["moderation.UserFilter"](for_artist=True) + hidden_album = factories["music.Album"](artist=cf.target_artist) qs = models.Album.objects.all() diff --git a/changes/changelog.d/1803.bugfix b/changes/changelog.d/1803.bugfix new file mode 100644 index 000000000..db04a4fb9 --- /dev/null +++ b/changes/changelog.d/1803.bugfix @@ -0,0 +1 @@ +Make Artist ordering by name case insensitive