From 84f830829fa52ce6882443b1c7b0e22166f26cf8 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Thu, 25 Jul 2019 10:50:23 +0200
Subject: [PATCH] See #432: include tags in admin API representation of tracks,
 albums and artists

---
 api/funkwhale_api/manage/filters.py     | 15 +++------------
 api/funkwhale_api/manage/serializers.py | 18 ++++++++++++++++++
 api/funkwhale_api/manage/views.py       |  5 ++++-
 api/tests/manage/test_serializers.py    |  3 +++
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/api/funkwhale_api/manage/filters.py b/api/funkwhale_api/manage/filters.py
index 3ce55e03..af9ded74 100644
--- a/api/funkwhale_api/manage/filters.py
+++ b/api/funkwhale_api/manage/filters.py
@@ -62,10 +62,7 @@ class ManageArtistFilterSet(filters.FilterSet):
                     "field": forms.IntegerField(),
                     "distinct": True,
                 },
-                "tag": {
-                    "to": "tagged_items__tag__name",
-                    "distinct": True,
-                },
+                "tag": {"to": "tagged_items__tag__name", "distinct": True},
             },
         )
     )
@@ -95,10 +92,7 @@ class ManageAlbumFilterSet(filters.FilterSet):
                     "field": forms.IntegerField(),
                     "distinct": True,
                 },
-                "tag": {
-                    "to": "tagged_items__tag__name",
-                    "distinct": True,
-                },
+                "tag": {"to": "tagged_items__tag__name", "distinct": True},
             },
         )
     )
@@ -137,10 +131,7 @@ class ManageTrackFilterSet(filters.FilterSet):
                     "field": forms.IntegerField(),
                     "distinct": True,
                 },
-                "tag": {
-                    "to": "tagged_items__tag__name",
-                    "distinct": True,
-                },
+                "tag": {"to": "tagged_items__tag__name", "distinct": True},
             },
         )
     )
diff --git a/api/funkwhale_api/manage/serializers.py b/api/funkwhale_api/manage/serializers.py
index 6eecdd90..3ea390b8 100644
--- a/api/funkwhale_api/manage/serializers.py
+++ b/api/funkwhale_api/manage/serializers.py
@@ -377,6 +377,7 @@ class ManageArtistSerializer(ManageBaseArtistSerializer):
     albums = ManageNestedAlbumSerializer(many=True)
     tracks = ManageNestedTrackSerializer(many=True)
     attributed_to = ManageBaseActorSerializer()
+    tags = serializers.SerializerMethodField()
 
     class Meta:
         model = music_models.Artist
@@ -384,8 +385,13 @@ class ManageArtistSerializer(ManageBaseArtistSerializer):
             "albums",
             "tracks",
             "attributed_to",
+            "tags",
         ]
 
+    def get_tags(self, obj):
+        tagged_items = getattr(obj, "_prefetched_tagged_items", [])
+        return [ti.tag.name for ti in tagged_items]
+
 
 class ManageNestedArtistSerializer(ManageBaseArtistSerializer):
     pass
@@ -395,6 +401,7 @@ class ManageAlbumSerializer(ManageBaseAlbumSerializer):
     tracks = ManageNestedTrackSerializer(many=True)
     attributed_to = ManageBaseActorSerializer()
     artist = ManageNestedArtistSerializer()
+    tags = serializers.SerializerMethodField()
 
     class Meta:
         model = music_models.Album
@@ -402,8 +409,13 @@ class ManageAlbumSerializer(ManageBaseAlbumSerializer):
             "artist",
             "tracks",
             "attributed_to",
+            "tags",
         ]
 
+    def get_tags(self, obj):
+        tagged_items = getattr(obj, "_prefetched_tagged_items", [])
+        return [ti.tag.name for ti in tagged_items]
+
 
 class ManageTrackAlbumSerializer(ManageBaseAlbumSerializer):
     artist = ManageNestedArtistSerializer()
@@ -418,6 +430,7 @@ class ManageTrackSerializer(ManageNestedTrackSerializer):
     album = ManageTrackAlbumSerializer()
     attributed_to = ManageBaseActorSerializer()
     uploads_count = serializers.SerializerMethodField()
+    tags = serializers.SerializerMethodField()
 
     class Meta:
         model = music_models.Track
@@ -426,11 +439,16 @@ class ManageTrackSerializer(ManageNestedTrackSerializer):
             "album",
             "attributed_to",
             "uploads_count",
+            "tags",
         ]
 
     def get_uploads_count(self, obj):
         return getattr(obj, "uploads_count", None)
 
+    def get_tags(self, obj):
+        tagged_items = getattr(obj, "_prefetched_tagged_items", [])
+        return [ti.tag.name for ti in tagged_items]
+
 
 class ManageTrackActionSerializer(common_serializers.ActionSerializer):
     actions = [common_serializers.Action("delete", allow_all=False)]
diff --git a/api/funkwhale_api/manage/views.py b/api/funkwhale_api/manage/views.py
index 9ecd1fee..ab6c0c9f 100644
--- a/api/funkwhale_api/manage/views.py
+++ b/api/funkwhale_api/manage/views.py
@@ -12,6 +12,7 @@ from funkwhale_api.federation import models as federation_models
 from funkwhale_api.federation import tasks as federation_tasks
 from funkwhale_api.history import models as history_models
 from funkwhale_api.music import models as music_models
+from funkwhale_api.music import views as music_views
 from funkwhale_api.moderation import models as moderation_models
 from funkwhale_api.playlists import models as playlists_models
 from funkwhale_api.tags import models as tags_models
@@ -71,6 +72,7 @@ class ManageArtistViewSet(
                     tracks_count=Count("tracks")
                 ),
             ),
+            music_views.TAG_PREFETCH,
         )
     )
     serializer_class = serializers.ManageArtistSerializer
@@ -108,7 +110,7 @@ class ManageAlbumViewSet(
         music_models.Album.objects.all()
         .order_by("-id")
         .select_related("attributed_to", "artist")
-        .prefetch_related("tracks")
+        .prefetch_related("tracks", music_views.TAG_PREFETCH)
     )
     serializer_class = serializers.ManageAlbumSerializer
     filterset_class = filters.ManageAlbumFilterSet
@@ -152,6 +154,7 @@ class ManageTrackViewSet(
         .order_by("-id")
         .select_related("attributed_to", "artist", "album__artist")
         .annotate(uploads_count=Coalesce(Subquery(uploads_subquery), 0))
+        .prefetch_related(music_views.TAG_PREFETCH)
     )
     serializer_class = serializers.ManageTrackSerializer
     filterset_class = filters.ManageTrackFilterSet
diff --git a/api/tests/manage/test_serializers.py b/api/tests/manage/test_serializers.py
index af2a214a..201f14ed 100644
--- a/api/tests/manage/test_serializers.py
+++ b/api/tests/manage/test_serializers.py
@@ -297,6 +297,7 @@ def test_manage_artist_serializer(factories, now):
         "attributed_to": serializers.ManageBaseActorSerializer(
             artist.attributed_to
         ).data,
+        "tags": [],
     }
     s = serializers.ManageArtistSerializer(artist)
 
@@ -387,6 +388,7 @@ def test_manage_album_serializer(factories, now):
         "attributed_to": serializers.ManageBaseActorSerializer(
             album.attributed_to
         ).data,
+        "tags": [],
     }
     s = serializers.ManageAlbumSerializer(album)
 
@@ -414,6 +416,7 @@ def test_manage_track_serializer(factories, now):
             track.attributed_to
         ).data,
         "uploads_count": 44,
+        "tags": [],
     }
     s = serializers.ManageTrackSerializer(track)
 
-- 
GitLab