Skip to content
Snippets Groups Projects
Commit 2e0883d4 authored by Ciarán Ainsworth's avatar Ciarán Ainsworth Committed by Eliot Berriot
Browse files

Fix #895: "Display tracks count instead of albums count for artists with no albums"

parent 7e8e21e1
Branches
Tags
No related merge requests found
...@@ -79,6 +79,7 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer): ...@@ -79,6 +79,7 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
albums = ArtistAlbumSerializer(many=True, read_only=True) albums = ArtistAlbumSerializer(many=True, read_only=True)
tags = serializers.SerializerMethodField() tags = serializers.SerializerMethodField()
attributed_to = serializers.SerializerMethodField() attributed_to = serializers.SerializerMethodField()
tracks_count = serializers.SerializerMethodField()
class Meta: class Meta:
model = models.Artist model = models.Artist
...@@ -92,6 +93,7 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer): ...@@ -92,6 +93,7 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
"is_local", "is_local",
"tags", "tags",
"attributed_to", "attributed_to",
"tracks_count",
) )
def get_tags(self, obj): def get_tags(self, obj):
...@@ -100,6 +102,9 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer): ...@@ -100,6 +102,9 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
get_attributed_to = serialize_attributed_to get_attributed_to = serialize_attributed_to
def get_tracks_count(self, o):
return getattr(o, "_tracks_count", None)
class ArtistSimpleSerializer(serializers.ModelSerializer): class ArtistSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
......
...@@ -94,7 +94,11 @@ def refetch_obj(obj, queryset): ...@@ -94,7 +94,11 @@ def refetch_obj(obj, queryset):
class ArtistViewSet(common_views.SkipFilterForGetObject, viewsets.ReadOnlyModelViewSet): class ArtistViewSet(common_views.SkipFilterForGetObject, viewsets.ReadOnlyModelViewSet):
queryset = models.Artist.objects.all().select_related("attributed_to") queryset = (
models.Artist.objects.all()
.select_related("attributed_to")
.annotate(_tracks_count=Count("tracks"))
)
serializer_class = serializers.ArtistWithAlbumsSerializer serializer_class = serializers.ArtistWithAlbumsSerializer
permission_classes = [oauth_permissions.ScopePermission] permission_classes = [oauth_permissions.ScopePermission]
required_scope = "libraries" required_scope = "libraries"
......
...@@ -62,7 +62,7 @@ def test_artist_with_albums_serializer(factories, to_api_date): ...@@ -62,7 +62,7 @@ def test_artist_with_albums_serializer(factories, to_api_date):
artist = track.artist artist = track.artist
artist = artist.__class__.objects.with_albums().get(pk=artist.pk) artist = artist.__class__.objects.with_albums().get(pk=artist.pk)
album = list(artist.albums.all())[0] album = list(artist.albums.all())[0]
setattr(artist, "_tracks_count", 42)
expected = { expected = {
"id": artist.id, "id": artist.id,
"fid": artist.fid, "fid": artist.fid,
...@@ -73,6 +73,7 @@ def test_artist_with_albums_serializer(factories, to_api_date): ...@@ -73,6 +73,7 @@ def test_artist_with_albums_serializer(factories, to_api_date):
"albums": [serializers.ArtistAlbumSerializer(album).data], "albums": [serializers.ArtistAlbumSerializer(album).data],
"tags": [], "tags": [],
"attributed_to": federation_serializers.APIActorSerializer(actor).data, "attributed_to": federation_serializers.APIActorSerializer(actor).data,
"tracks_count": 42,
} }
serializer = serializers.ArtistWithAlbumsSerializer(artist) serializer = serializers.ArtistWithAlbumsSerializer(artist)
assert serializer.data == expected assert serializer.data == expected
......
...@@ -6,6 +6,7 @@ import urllib.parse ...@@ -6,6 +6,7 @@ import urllib.parse
import uuid import uuid
import pytest import pytest
from django.db.models import Count
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
...@@ -27,7 +28,7 @@ def test_artist_list_serializer(api_request, factories, logged_in_api_client): ...@@ -27,7 +28,7 @@ def test_artist_list_serializer(api_request, factories, logged_in_api_client):
).track ).track
artist = track.artist artist = track.artist
request = api_request.get("/") request = api_request.get("/")
qs = artist.__class__.objects.with_albums() qs = artist.__class__.objects.with_albums().annotate(_tracks_count=Count("tracks"))
serializer = serializers.ArtistWithAlbumsSerializer( serializer = serializers.ArtistWithAlbumsSerializer(
qs, many=True, context={"request": request} qs, many=True, context={"request": request}
) )
......
Artists with no albums will now show track count on artist card (#895)
\ No newline at end of file
...@@ -1190,6 +1190,10 @@ definitions: ...@@ -1190,6 +1190,10 @@ definitions:
- $ref: "#/definitions/BaseArtist" - $ref: "#/definitions/BaseArtist"
- type: "object" - type: "object"
properties: properties:
tracks_count:
type: "integer"
format: "int64"
example: 42
albums: albums:
type: "array" type: "array"
items: items:
......
...@@ -7,10 +7,14 @@ ...@@ -7,10 +7,14 @@
<router-link :title="artist.name" :to="{name: 'library.artists.detail', params: {id: artist.id}}"> <router-link :title="artist.name" :to="{name: 'library.artists.detail', params: {id: artist.id}}">
{{ artist.name|truncate(30) }} {{ artist.name|truncate(30) }}
</router-link> </router-link>
<div> <div v-if="artist.albums.length > 0">
<i class="small sound icon"></i> <i class="small sound icon"></i>
<translate translate-context="Content/Artist/Card" :translate-params="{count: artist.albums.length}" :translate-n="artist.albums.length" translate-plural="%{ count } albums">1 album</translate> <translate translate-context="Content/Artist/Card" :translate-params="{count: artist.albums.length}" :translate-n="artist.albums.length" translate-plural="%{ count } albums">1 album</translate>
</div> </div>
<div v-else-if="artist.tracks_count">
<i class="small sound icon"></i>
<translate translate-context="Content/Artist/Card" :translate-params="{count: artist.tracks_count}" :translate-n="artist.tracks_count" translate-plural="%{ count } tracks">1 track</translate>
</div>
<tags-list label-classes="tiny" :truncate-size="20" :limit="2" :show-more="false" :tags="artist.tags"></tags-list> <tags-list label-classes="tiny" :truncate-size="20" :limit="2" :show-more="false" :tags="artist.tags"></tags-list>
<play-button <play-button
...@@ -38,11 +42,10 @@ export default { ...@@ -38,11 +42,10 @@ export default {
return { return {
backend: backend, backend: backend,
initialAlbums: 30, initialAlbums: 30,
showAllAlbums: true showAllAlbums: true,
} }
}, },
computed: { computed: {
imageUrl () { imageUrl () {
let url = '../../../assets/audio/default-cover.png' let url = '../../../assets/audio/default-cover.png'
let cover = this.cover let cover = this.cover
...@@ -59,7 +62,7 @@ export default { ...@@ -59,7 +62,7 @@ export default {
}).filter((c) => { }).filter((c) => {
return !!c return !!c
})[0] || {} })[0] || {}
} },
} }
} }
</script> </script>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment