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): ...@@ -11,6 +11,8 @@ class Playlist(models.Model):
user = models.ForeignKey( user = models.ForeignKey(
'users.User', related_name="playlists", on_delete=models.CASCADE) 'users.User', related_name="playlists", on_delete=models.CASCADE)
creation_date = models.DateTimeField(default=timezone.now) creation_date = models.DateTimeField(default=timezone.now)
modification_date = models.DateTimeField(
auto_now=True)
privacy_level = fields.get_privacy_field() privacy_level = fields.get_privacy_field()
def __str__(self): def __str__(self):
...@@ -65,10 +67,13 @@ class Playlist(models.Model): ...@@ -65,10 +67,13 @@ class Playlist(models.Model):
plt.index = index plt.index = index
plt.save(update_fields=['index']) plt.save(update_fields=['index'])
self.save(update_fields=['modification_date'])
return index return index
@transaction.atomic
def remove(self, index): def remove(self, index):
existing = self.playlist_tracks.select_for_update() existing = self.playlist_tracks.select_for_update()
self.save(update_fields=['modification_date'])
to_update = existing.filter(index__gt=index) to_update = existing.filter(index__gt=index)
return to_update.update(index=models.F('index') - 1) return to_update.update(index=models.F('index') - 1)
......
...@@ -62,8 +62,25 @@ class PlaylistTrackWriteSerializer(serializers.ModelSerializer): ...@@ -62,8 +62,25 @@ class PlaylistTrackWriteSerializer(serializers.ModelSerializer):
class PlaylistSerializer(serializers.ModelSerializer): class PlaylistSerializer(serializers.ModelSerializer):
tracks_count = serializers.SerializerMethodField()
class Meta: class Meta:
model = models.Playlist model = models.Playlist
fields = ('id', 'name', 'privacy_level', 'creation_date') fields = (
read_only_fields = ['id', 'creation_date'] '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 generics, mixins, viewsets
from rest_framework import status from rest_framework import status
from rest_framework.decorators import detail_route from rest_framework.decorators import detail_route
...@@ -8,6 +10,7 @@ from funkwhale_api.music.models import Track ...@@ -8,6 +10,7 @@ from funkwhale_api.music.models import Track
from funkwhale_api.common import permissions from funkwhale_api.common import permissions
from funkwhale_api.common import fields from funkwhale_api.common import fields
from . import filters
from . import models from . import models
from . import serializers from . import serializers
...@@ -21,13 +24,17 @@ class PlaylistViewSet( ...@@ -21,13 +24,17 @@ class PlaylistViewSet(
viewsets.GenericViewSet): viewsets.GenericViewSet):
serializer_class = serializers.PlaylistSerializer serializer_class = serializers.PlaylistSerializer
queryset = (models.Playlist.objects.all()) queryset = (
models.Playlist.objects.all()
.annotate(tracks_count=Count('playlist_tracks'))
)
permission_classes = [ permission_classes = [
permissions.ConditionalAuthentication, permissions.ConditionalAuthentication,
permissions.OwnerPermission, permissions.OwnerPermission,
IsAuthenticatedOrReadOnly, IsAuthenticatedOrReadOnly,
] ]
owner_checks = ['write'] owner_checks = ['write']
filter_class = filters.PlaylistFilter
@detail_route(methods=['get']) @detail_route(methods=['get'])
def tracks(self, request, *args, **kwargs): def tracks(self, request, *args, **kwargs):
......
...@@ -5,6 +5,7 @@ from django import forms ...@@ -5,6 +5,7 @@ from django import forms
def test_can_insert_plt(factories): def test_can_insert_plt(factories):
plt = factories['playlists.PlaylistTrack']() plt = factories['playlists.PlaylistTrack']()
modification_date = plt.playlist.modification_date
assert plt.index is None assert plt.index is None
...@@ -12,6 +13,7 @@ def test_can_insert_plt(factories): ...@@ -12,6 +13,7 @@ def test_can_insert_plt(factories):
plt.refresh_from_db() plt.refresh_from_db()
assert plt.index == 0 assert plt.index == 0
assert plt.playlist.modification_date > modification_date
def test_insert_use_last_idx_by_default(factories): def test_insert_use_last_idx_by_default(factories):
......
...@@ -23,6 +23,16 @@ def test_can_create_playlist_via_api(logged_in_api_client): ...@@ -23,6 +23,16 @@ def test_can_create_playlist_via_api(logged_in_api_client):
assert playlist.privacy_level == 'everyone' 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): def test_playlist_inherits_user_privacy(logged_in_api_client):
url = reverse('api:v1:playlists-list') url = reverse('api:v1:playlists-list')
user = logged_in_api_client.user 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