You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django音乐应用添加歌曲至播放列表功能失效问题求助

Django音乐流媒体网站:添加歌曲到播放列表失败排查修复

我正在开发首个Django音乐流媒体网站,实现将歌曲添加至指定播放列表的视图时出现异常,始终弹出“failed to add song to playlist”错误,歌曲无法成功加入播放列表。以下是相关代码,请求协助排查修复:

HTML代码

{% if my_playlists %}
        <p style="">Add This Song To Your Playlist</p>
        {% for playlist in my_playlists %}
            <a class="left-panel-btn" id="D_{{playlist.playlist_id}}" onclick="sendPostRequestPlaylistSong(this)">{{playlist.playlist_name}}</a><br>
        {% endfor %}
{% else %}
        <p style="">You don't have any Playlist.</p>
        <a class="create-p" onclick="$('#divId').css({display: 'none'}); document.getElementById('modal-wrapper-playlist').style.display='block'"><i class="fas fa-plus"></i> Create Playlist</a>
{% endif %}

JavaScript函数

function sendPostRequestPlaylistSong(el) {
        // alert("Song ID: "+song_id_for_playlist+" | Playlist ID: "+el.id);
        var data = song_id_for_playlist + "|" + el.id;
        $.ajax({
            "url": "{% url 'music:addSongToPlaylist' %}",
            "type": "POST",
            "data": { 'data': data, 'csrfmiddlewaretoken': '{{ csrf_token }}' },
            success: function(response) {
            alert("Song added to your playlist");
            location.reload();},
            error: function(xhr, status, error) {
            alert("Failed to add song to playlist.");}
            });
        var div = $("#divId");
        div.css({
            transition: "0.3s",
            display: "none"
        });
    }

views.py代码

def addSongToPlaylist(request):
user = request.user
if request.method == "POST" and user.is_authenticated:
    data = request.POST['data']
    if data:
        song_id, playlist_id = data.split("|")
        song_id = song_id[0][2:]
        playlist_id = playlist_id[1][2:]
        currPlaylist = Playlist.objects.filter(playlist_id=playlist_id, user=request.user).first()
        song = Song.objects.filter(song_id=song_id).first()
        if song not in currPlaylist.songs.all():
            currPlaylist.songs.add(song)
            currPlaylist.plays = currPlaylist.songs.count()
            currPlaylist.save()
            messages.success(request, "Song added successfully")
        return HttpResponse("Successfull")
else:
    return redirect("users:login")


def playlist(request, playlist_id):
user = request.user
if user.is_authenticated:
    myPlaylists = Playlist.objects.filter(user=user)
    if request.method == "POST":
        song_id = request.POST["music_id"]
        playlist = Playlist.objects.filter(playlist_id=playlist_id).first()
        if song_id in playlist.songs.all():
            playlist.songs.remove(song_id)
            playlist.plays -= 1
            playlist.save()
        message = "Successfull"
        print(message)
        return HttpResponse(json.dumps({'message': message}))
    else:
        images = os.listdir("media/playlist_images")
        currPlaylist = Playlist.objects.filter(playlist_id=playlist_id).first()
        songs = currPlaylist.songs
        playlistSongs = [currPlaylist.songs.all()]
        recommendedSingers = []
        return render(request, "music/playlist.html", {'playlistInfo': currPlaylist,
                                                       'playlistSongs': playlistSongs,
                                                       'myPlaylists': myPlaylists,
                                                       'recommendedSingers': recommendedSingers})

models.py代码

class Playlist(models.Model):
playlist_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
playlist_name = models.CharField(max_length=50, default="name")
image = models.ImageField(upload_to="playlist_images/", validators=[FileExtensionValidator(allowed_extensions=['jpeg', 'jpg', 'png'])], blank=True)
plays = models.IntegerField(default=0)
songs = models.ManyToManyField(Song, related_name='playlist')
slug = models.SlugField()

排查修复要点

1. 数据解析逻辑错误

addSongToPlaylist视图中,拆分数据后的处理完全错误:

song_id = song_id[0][2:]
playlist_id = playlist_id[1][2:]
  • song_id是song_id_for_playlist的完整值,不需要取[0][2:],这会导致截取错误的内容
  • playlist_id来自元素id(格式为D_123),正确处理应该拆分_获取后面的数字

修复代码:

song_id, playlist_id_str = data.split("|")
# 提取playlist_id
playlist_id = playlist_id_str.split("_")[1]

2. 空对象异常处理缺失

如果currPlaylist或song查询返回None,后续代码会抛出异常,触发AJAX错误回调。需要添加判断确保对象存在:

修复后的addSongToPlaylist视图:

def addSongToPlaylist(request):
    user = request.user
    if request.method == "POST" and user.is_authenticated:
        data = request.POST.get('data')
        if not data:
            return HttpResponse("Invalid data", status=400)
        
        try:
            song_id, playlist_id_str = data.split("|")
        except ValueError:
            return HttpResponse("Invalid data format", status=400)
        
        playlist_id = playlist_id_str.split("_")[1]
        currPlaylist = Playlist.objects.filter(playlist_id=playlist_id, user=request.user).first()
        song = Song.objects.filter(song_id=song_id).first()
        
        if not currPlaylist or not song:
            return HttpResponse("Playlist or Song not found", status=404)
        
        if song not in currPlaylist.songs.all():
            currPlaylist.songs.add(song)
            currPlaylist.plays = currPlaylist.songs.count()
            currPlaylist.save()
            messages.success(request, "Song added successfully")
        
        return HttpResponse("Successfull")
    else:
        return redirect("users:login")

3. AJAX错误信息优化

当前AJAX错误提示无法获取具体错误原因,修改为打印详情方便调试:

error: function(xhr, status, error) {
    console.error("Error details:", xhr.responseText, status, error);
    alert("Failed to add song to playlist. Error: " + xhr.responseText);
}

4. playlist视图的判断逻辑错误

playlist视图POST分支中,if song_id in playlist.songs.all()逻辑错误:songs.all()返回对象列表,无法直接与字符串id比较。

修复代码:

if playlist.songs.filter(song_id=song_id).exists():
    playlist.songs.remove(song_id)
    playlist.plays -= 1
    playlist.save()

内容的提问来源于stack exchange,提问作者Federico Monetti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:14:55