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
相关产品推荐
相关产品推荐

