New "index" field on playlist tracks, and .insert() metod to manage playlists

This commit is contained in:
Eliot Berriot 2018-03-19 14:11:09 +01:00
parent 8821a1bb43
commit 257e67b5a6
No known key found for this signature in database
GPG key ID: DD6965E2476E5C27
5 changed files with 175 additions and 21 deletions

View file

@ -1,4 +1,6 @@
from django import forms
from django.db import models
from django.db import transaction
from django.utils import timezone
from funkwhale_api.common import fields
@ -14,14 +16,59 @@ class Playlist(models.Model):
def __str__(self):
return self.name
def add_track(self, track, previous=None):
plt = PlaylistTrack(previous=previous, track=track, playlist=self)
plt.save()
@transaction.atomic
def insert(self, plt, index=None):
"""
Given a PlaylistTrack, insert it at the correct index in the playlist,
and update other tracks index if necessary.
"""
old_index = plt.index
move = old_index is not None
if index is not None and index == old_index:
# moving at same position, just skip
return index
return plt
existing = self.playlist_tracks.select_for_update()
if move:
existing = existing.exclude(pk=plt.pk)
total = existing.filter(index__isnull=False).count()
if index is None:
# we simply increment the last track index by 1
index = total
if index > total:
raise forms.ValidationError('Index is not continuous')
if index < 0:
raise forms.ValidationError('Index must be zero or positive')
if move:
# we remove the index temporarily, to avoid integrity errors
plt.index = None
plt.save(update_fields=['index'])
if move:
if index > old_index:
# new index is higher than current, we decrement previous tracks
to_update = existing.filter(
index__gt=old_index, index__lte=index)
to_update.update(index=models.F('index') - 1)
if index < old_index:
# new index is lower than current, we increment next tracks
to_update = existing.filter(
index__lt=old_index, index__gte=index)
to_update.update(index=models.F('index') + 1)
else:
to_update = existing.filter(index__gte=index)
to_update.update(index=models.F('index') + 1)
plt.index = index
plt.save(update_fields=['index'])
return index
class PlaylistTrack(MPTTModel):
class PlaylistTrack(models.Model):
track = models.ForeignKey(
'music.Track',
related_name='playlist_tracks',
@ -29,6 +76,7 @@ class PlaylistTrack(MPTTModel):
index = models.PositiveIntegerField(null=True)
playlist = models.ForeignKey(
Playlist, related_name='playlist_tracks', on_delete=models.CASCADE)
creation_date = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ('-playlist', 'index')