diff --git a/api/funkwhale_api/playlists/migrations/0004_auto_20180319_1642.py b/api/funkwhale_api/playlists/migrations/0004_auto_20180319_1642.py new file mode 100644 index 0000000000000000000000000000000000000000..f4a52529105cc00759f2392b8ecb1ab350058e31 --- /dev/null +++ b/api/funkwhale_api/playlists/migrations/0004_auto_20180319_1642.py @@ -0,0 +1,23 @@ +# Generated by Django 2.0.3 on 2018-03-19 16:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('playlists', '0003_auto_20180319_1214'), + ] + + operations = [ + migrations.AddField( + model_name='playlist', + name='modification_date', + field=models.DateTimeField(auto_now=True), + ), + migrations.AlterField( + model_name='playlisttrack', + name='index', + field=models.PositiveIntegerField(blank=True, null=True), + ), + ] diff --git a/api/funkwhale_api/playlists/models.py b/api/funkwhale_api/playlists/models.py index d8c90aef9ab46626aa2750a80a9e6c333f12fe5d..f26dbeff4f48f41db151ee0f9aee5445301fb3c0 100644 --- a/api/funkwhale_api/playlists/models.py +++ b/api/funkwhale_api/playlists/models.py @@ -11,6 +11,8 @@ class Playlist(models.Model): user = models.ForeignKey( 'users.User', related_name="playlists", on_delete=models.CASCADE) creation_date = models.DateTimeField(default=timezone.now) + modification_date = models.DateTimeField( + auto_now=True) privacy_level = fields.get_privacy_field() def __str__(self): @@ -65,10 +67,13 @@ class Playlist(models.Model): plt.index = index plt.save(update_fields=['index']) + self.save(update_fields=['modification_date']) return index + @transaction.atomic def remove(self, index): existing = self.playlist_tracks.select_for_update() + self.save(update_fields=['modification_date']) to_update = existing.filter(index__gt=index) return to_update.update(index=models.F('index') - 1) diff --git a/api/funkwhale_api/playlists/serializers.py b/api/funkwhale_api/playlists/serializers.py index 43e2414d404c8694829cb6cc3fb2f8f851b7bd17..0680dc8d0a82b36b25feeac11e48e5b3ed8656b7 100644 --- a/api/funkwhale_api/playlists/serializers.py +++ b/api/funkwhale_api/playlists/serializers.py @@ -62,8 +62,25 @@ class PlaylistTrackWriteSerializer(serializers.ModelSerializer): class PlaylistSerializer(serializers.ModelSerializer): + tracks_count = serializers.SerializerMethodField() class Meta: model = models.Playlist - fields = ('id', 'name', 'privacy_level', 'creation_date') - read_only_fields = ['id', 'creation_date'] + fields = ( + 'id', + 'name', + 'tracks_count', + 'privacy_level', + 'creation_date', + 'modification_date') + read_only_fields = [ + 'id', + 'modification_date', + 'creation_date',] + + def get_tracks_count(self, obj): + try: + return obj.tracks_count + except AttributeError: + # no annotation? + return obj.playlist_tracks.count() diff --git a/api/funkwhale_api/playlists/views.py b/api/funkwhale_api/playlists/views.py index 02e53cb169bae11cf8c5141c77942e91126108e9..dc3475fab07678b2a6d617354ad9f8e77f97698f 100644 --- a/api/funkwhale_api/playlists/views.py +++ b/api/funkwhale_api/playlists/views.py @@ -1,3 +1,5 @@ +from django.db.models import Count + from rest_framework import generics, mixins, viewsets from rest_framework import status from rest_framework.decorators import detail_route @@ -8,6 +10,7 @@ from funkwhale_api.music.models import Track from funkwhale_api.common import permissions from funkwhale_api.common import fields +from . import filters from . import models from . import serializers @@ -21,13 +24,17 @@ class PlaylistViewSet( viewsets.GenericViewSet): serializer_class = serializers.PlaylistSerializer - queryset = (models.Playlist.objects.all()) + queryset = ( + models.Playlist.objects.all() + .annotate(tracks_count=Count('playlist_tracks')) + ) permission_classes = [ permissions.ConditionalAuthentication, permissions.OwnerPermission, IsAuthenticatedOrReadOnly, ] owner_checks = ['write'] + filter_class = filters.PlaylistFilter @detail_route(methods=['get']) def tracks(self, request, *args, **kwargs): diff --git a/api/tests/playlists/test_models.py b/api/tests/playlists/test_models.py index dfe40187d8278a9853fd90917c70a4384bd018e5..da3e23e280a6bfc431f41efca0eec4adbed68275 100644 --- a/api/tests/playlists/test_models.py +++ b/api/tests/playlists/test_models.py @@ -5,6 +5,7 @@ from django import forms def test_can_insert_plt(factories): plt = factories['playlists.PlaylistTrack']() + modification_date = plt.playlist.modification_date assert plt.index is None @@ -12,6 +13,7 @@ def test_can_insert_plt(factories): plt.refresh_from_db() assert plt.index == 0 + assert plt.playlist.modification_date > modification_date def test_insert_use_last_idx_by_default(factories): diff --git a/api/tests/playlists/test_views.py b/api/tests/playlists/test_views.py index 192aad382469d50315c23df21ac42d7e1f06c10d..03babfabb51e3490ce7877774fd24e71269531a8 100644 --- a/api/tests/playlists/test_views.py +++ b/api/tests/playlists/test_views.py @@ -23,6 +23,16 @@ def test_can_create_playlist_via_api(logged_in_api_client): assert playlist.privacy_level == 'everyone' +def test_serializer_includes_tracks_count(factories, logged_in_api_client): + playlist = factories['playlists.Playlist']() + plt = factories['playlists.PlaylistTrack'](playlist=playlist) + + url = reverse('api:v1:playlists-detail', kwargs={'pk': playlist.pk}) + response = logged_in_api_client.get(url) + + assert response.data['tracks_count'] == 1 + + def test_playlist_inherits_user_privacy(logged_in_api_client): url = reverse('api:v1:playlists-list') user = logged_in_api_client.user