Django REST Framework添加歌曲到播放列表报错及展示歌曲问题
问题解决步骤
一、修复AddToPlaylist视图错误(按播放列表名称关联歌曲)
当前错误核心是:你直接将前端传入的播放列表名称字符串赋值给Song的playlist字段,但该字段要求的是Playlist模型实例,而非字符串。修改代码如下:
from django.shortcuts import get_object_or_404 from rest_framework import status class AddToPlaylist(APIView): serializer_class = SongSerializer def post(self, request, format=None): if not self.request.session.exists(self.request.session.session_key): self.request.session.create() serializer = self.serializer_class(data=request.data) if serializer.is_valid(): name = serializer.data.get("name") artist = serializer.data.get("artist") album = serializer.data.get("album") playlist_name = serializer.data.get("playlist") # 根据名称查询对应播放列表,不存在则返回404 playlist = get_object_or_404(Playlist, name=playlist_name) # 创建歌曲并关联到目标播放列表 song = Song(name=name, artist=artist, album=album, playlist=playlist) song.save() return Response(SongSerializer(song).data, status=status.HTTP_201_CREATED) # 返回验证失败的错误信息 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
提示:如果存在同名播放列表的场景,建议改用播放列表ID关联(更可靠),此时前端传
playlist_id,视图中替换为get_object_or_404(Playlist, id=playlist_id)。
二、在PlaylistView中展示播放列表内的歌曲
要让播放列表数据包含关联的所有歌曲,需要修改序列化器实现嵌套序列化:
1. 完善SongSerializer(确保序列化歌曲基础信息)
在serializers.py中定义基础的歌曲序列化器:
from rest_framework import serializers from .models import Playlist, Song class SongSerializer(serializers.ModelSerializer): class Meta: model = Song fields = ['id', 'name', 'artist', 'album', 'date_added']
2. 修改PlaylistSerializer,添加歌曲列表字段
通过反向关联的song_set(Django默认的反向查询集名称),将歌曲列表嵌套到播放列表数据中:
class PlaylistSerializer(serializers.ModelSerializer): # 用source指定关联的歌曲查询集,many=True表示返回多个歌曲 songs = SongSerializer(many=True, source='song_set', read_only=True) class Meta: model = Playlist fields = ['id', 'name', 'description', 'date_created', 'date_updated', 'songs']
3. 优化PlaylistView查询性能(避免N+1查询)
为了提升接口性能,提前预加载所有播放列表的关联歌曲:
class PlaylistView(generics.ListAPIView): # 用prefetch_related预加载歌曲数据,避免多次查询数据库 queryset = Playlist.objects.all().prefetch_related('song_set') serializer_class = PlaylistSerializer
修改完成后,请求播放列表列表接口时,每个播放列表对象都会包含songs字段,展示该列表下的所有歌曲信息。
内容的提问来源于stack exchange,提问作者Vedant Bisen
相关产品推荐
相关产品推荐

