Skip to content
Snippets Groups Projects
models.py 3.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • from funkwhale_api.common import fields
    
    
    
    class Playlist(models.Model):
        name = models.CharField(max_length=50)
    
        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()
    
        @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
    
            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'])
    
            self.save(update_fields=['modification_date'])
    
        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)
    
    
        track = models.ForeignKey(
            'music.Track',
            related_name='playlist_tracks',
            on_delete=models.CASCADE)
    
        index = models.PositiveIntegerField(null=True, blank=True)
    
        playlist = models.ForeignKey(
            Playlist, related_name='playlist_tracks', on_delete=models.CASCADE)
    
        creation_date = models.DateTimeField(default=timezone.now)
    
            ordering = ('-playlist', 'index')
            unique_together = ('playlist', 'index')
    
    
        def delete(self, *args, **kwargs):
            playlist = self.playlist
            index = self.index
            update_indexes = kwargs.pop('update_indexes', False)
            r = super().delete(*args, **kwargs)
            if index is not None and update_indexes:
                playlist.remove(index)
            return r