Django音乐应用用户播放列表无法显示问题排查
问题描述
我正在开发一个音乐流媒体网站,尝试在<div id="divId">中展示用户的播放列表,但页面始终显示“用户没有播放列表”,可数据库里明明存在对应用户的播放列表。问题出在哪?会不会是播放列表的视图逻辑有问题?
HTML代码
<div id="divId"> {% if myPlaylists %} <p style="margin: 5px; font-size: 0.75rem; font-weight: 700; color: rgb(138, 138, 138); text-align: left;">Add This Song To Your Playlist</p> {% for playlist in myPlaylists %} <a class="left-panel-btn" id="D_{{playlist.playlist_id}}" onclick="sendPostRequestPlaylistSong(this)">{{playlistInfo.playlist_name}}</a><br> {% endfor %} {% else %} <p style="margin: 5px; font-size: 0.8rem; font-weight: 700; color: rgb(138, 138, 138); text-align: left;">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 %} </div>
Models.py代码
class Song(models.Model): song_id = models.AutoField(primary_key=True) name = models.CharField(max_length=50) artist = models.CharField(max_length=50) album = models.CharField(max_length=50, blank=True) genre = models.CharField(max_length=20, blank=True, default='Album') song = models.FileField(upload_to="songs/", validators=[FileExtensionValidator(allowed_extensions=['mp3', 'wav'])], default="name") image = models.ImageField(upload_to="songimage/", validators=[FileExtensionValidator(allowed_extensions=['jpeg', 'jpg', 'png'])], default="https://placehold.co/300x300/png") data = models.DateTimeField(auto_now=False, auto_now_add=True) slug = models.SlugField() def __str__(self): return self.name class Meta: ordering = ['name'] 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'])], default="media/images/music-placeholder.png") plays = models.IntegerField(default=0) songs = models.ManyToManyField(Song, related_name='playlist') slug = models.SlugField() def __str__(self): return self.playlist_name
Views.py代码
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") print(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})
问题排查与修复方案
以下是几个关键问题点及对应的修复方法:
未处理用户未登录的边界情况
- 当前视图仅在
user.is_authenticated为True时才会查询myPlaylists并传递给模板,如果用户未登录,myPlaylists根本不会被传入模板,导致模板触发{% else %}分支,显示“无播放列表”。 - 修复:在视图开头初始化空查询集,确保所有分支都能传递
myPlaylists:def playlist(request, playlist_id): user = request.user myPlaylists = Playlist.objects.none() # 默认空查询集 if user.is_authenticated: myPlaylists = Playlist.objects.filter(user=user) # 后续代码保持不变,确保render或返回响应时都传递myPlaylists
- 当前视图仅在
模板循环中的变量错误
- HTML模板循环播放列表时,错误地使用了
{{playlistInfo.playlist_name}}(当前单个播放列表的名称),而不是循环项{{playlist.playlist_name}},即使播放列表能显示,也会重复显示同一个名称。 - 修复:修改循环内的变量:
{% for playlist in myPlaylists %} <a class="left-panel-btn" id="D_{{playlist.playlist_id}}" onclick="sendPostRequestPlaylistSong(this)">{{playlist.playlist_name}}</a><br> {% endfor %}
- HTML模板循环播放列表时,错误地使用了
POST请求中歌曲存在判断逻辑错误
if song_id in playlist.songs.all()的写法错误:playlist.songs.all()返回的是Song对象列表,而song_id是从POST中获取的字符串ID,两者无法直接比较,导致判断永远为False。- 修复:改用
exists()方法判断歌曲是否在播放列表中:song = Song.objects.get(song_id=song_id) if playlist.songs.filter(song_id=song_id).exists(): playlist.songs.remove(song) playlist.plays -= 1 playlist.save()
播放列表歌曲数据格式问题
playlistSongs = [currPlaylist.songs.all()]将查询集包裹在列表中,会导致模板遍历困难,应该直接传递查询集本身。- 修复:
playlistSongs = currPlaylist.songs.all()
验证用户与播放列表的关联关系
- 确认数据库中播放列表的
user字段确实关联到当前登录的用户,可以在视图中添加调试打印:print(f"当前用户: {user.username}, 查询到的播放列表数量: {myPlaylists.count()}") - 如果打印结果显示数量为0,检查数据库中播放列表的用户关联是否正确。
- 确认数据库中播放列表的
内容的提问来源于stack exchange,提问作者Federico Monetti
相关产品推荐
相关产品推荐

