Skip to content
Snippets Groups Projects
Verified Commit 08b28a7d authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Added playlist tracks count and modification date in API

parent d6f2c7d4
No related branches found
No related tags found
No related merge requests found
# 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),
),
]
......@@ -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)
......
......@@ -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()
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):
......
......@@ -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):
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment