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

Django报错:无法将ID赋值给Song.playlist,需传入Playlist实例

解决Django中"Cannot assign '1': 'Song.playlist' must be a 'Playlist' instance"报错

你遇到的报错核心原因是:Song模型的playlist字段要求接收Playlist模型实例,但你传入的是纯数字ID值。以下是三种可行的解决思路:


现有代码

models.py

class Playlist(models.Model):
    name = models.CharField(max_length="100")
    description = models.TextField()
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

class Song(models.Model):
    playlist = models.ForeignKey(Playlist, on_delete=models.CASCADE, null=True)
    name = models.CharField(max_length="100")
    artist = models.CharField(max_length="100")
    album = models.CharField(max_length="100")
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

views.py

class AddToPlaylist(APIView):
    serializer_class = AddToPlaylistSerializer

    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 = serializer.data.get("playlist")
            print(name, artist, album, playlist)
            song = Song(name=name, artist=artist, album=album, playlist=playlist)
            song.save()
            return Response(SongSerializer(song).data, status=status.HTTP_201_CREATED)

AddToPlaylistSerializer

class AddToPlaylistSerializer(serializers.ModelSerializer):
    class Meta:
        model = Song
        fields = ('name', 'artist', 'album', 'playlist')

解决方案

方案一:利用Serializer的save()方法(推荐)

ModelSerializer已经封装了外键的自动转换逻辑,直接调用serializer.save()即可完成实例创建,无需手动处理ID转实例的过程:

class AddToPlaylist(APIView):
    serializer_class = AddToPlaylistSerializer

    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():
            song = serializer.save()
            return Response(SongSerializer(song).data, status=status.HTTP_201_CREATED)

方案二:通过ID查询Playlist实例

如果必须手动创建Song对象,先通过ID查询对应的Playlist实例,再赋值给playlist字段(注意处理实例不存在的异常):

class AddToPlaylist(APIView):
    serializer_class = AddToPlaylistSerializer

    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_id = serializer.data.get("playlist")
            
            try:
                playlist = Playlist.objects.get(id=playlist_id)
            except Playlist.DoesNotExist:
                return Response({"error": "指定的播放列表不存在"}, status=status.HTTP_404_NOT_FOUND)
                
            song = Song(name=name, artist=artist, album=album, playlist=playlist)
            song.save()
            return Response(SongSerializer(song).data, status=status.HTTP_201_CREATED)

方案三:直接使用外键的ID字段赋值

Django允许通过外键字段名_id的形式直接赋值ID,无需提前查询实例:

class AddToPlaylist(APIView):
    serializer_class = AddToPlaylistSerializer

    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_id = serializer.data.get("playlist")
            
            song = Song(name=name, artist=artist, album=album, playlist_id=playlist_id)
            song.save()
            return Response(SongSerializer(song).data, status=status.HTTP_201_CREATED)

内容的提问来源于stack exchange,提问作者Vedant Bisen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:18:10