【问题标题】:How to deserialize an array of primary keys with Django Rest Framework PrimaryKeyRelatedField如何使用 Django Rest Framework PrimaryKeyRelatedField 反序列化主键数组
【发布时间】:2026-01-25 10:35:01
【问题描述】:

我在设置序列化程序时遵循了docs

class PlaylistSerializer(serializers.ModelSerializer):
    songs = serializers.PrimaryKeyRelatedField(queryset=Song.objects.all(), many=True, allow_empty=True, required=False)

    class Meta:
        model = Playlist
        fields = ['id', 'name', 'songs', 'created_at']

如果我在 django 管理员的播放列表中添加几首歌曲并发送一个 get 请求,我会得到我想要的结果。

{
    "id": 4,
    "name": "teszt3",
    "songs": [
        351,
        350
    ],
    "created_at": "2022-01-14T14:04:36.238350Z"
}

但我想使用类似的歌曲主键列表创建或更新播放列表。如果我使用此正文发送 POST 请求:

{
    "name": "test2",
    "songs": [350, 351]
}

我收到此错误:

Incorrect type. Expected pk value, received str

如果歌曲字段中只有一个数字(主键),它可以工作,但我想一次创建包含多首歌曲的播放列表。有没有办法解析该数组,或者我该如何解决?

编辑: 模型.py

class Song(models.Model):
    id = models.IntegerField(primary_key=True)
    title = models.CharField(max_length=256)
    lyrics = models.CharField(max_length=5000)
    verses = models.CharField(max_length=5000, blank=True, default='')

class Playlist(models.Model):
    name = models.CharField(max_length=256)
    created_at = models.DateTimeField(auto_now_add=True)
    songs = models.ManyToManyField(Song)

views.py

class SongViewSet(viewsets.ModelViewSet):
    queryset = Song.objects.all().order_by('id')
    serializer_class = SongSerializer

class PlaylistViewSet(viewsets.ModelViewSet):
    queryset = Playlist.objects.all().order_by('-created_at')
    serializer_class = PlaylistSerializer

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    您的模型或端点可能有一些错误。由于您没有提供该信息,因此这是一个与您的序列化程序完全兼容的工作示例。

    models.py

    class Song(models.Model):
        pass
    
    
    class Playlist(models.Model):
        name = models.CharField(max_length=50)
        songs = models.ManyToManyField(Song)
        created_at = models.DateTimeField(auto_now_add=True)
    

    views.py

    class CreatePlaylist(CreateAPIView):
        serializer_class = PlaylistSerializer
    

    【讨论】:

    • 我用这些文件的代码编辑了原始帖子,它们相似,只是我使用的是 Viewsets
    • 我试过你的代码,它工作正常,我知道你是怎么得到这个错误的。我从浏览器和测试中尝试过,两种情况都有效。
    • 我放弃了,自己写了views,只使用REST框架进行序列化,不反序列化。顺便说一句,这个后端是为 React 应用程序设计的,我从编写后端开始了新功能,所以我现在才开始在 React 中实现它。在我使用邮递员模拟请求之前,事实证明这是我出错的地方。我将请求正文作为 Formdata 发送,而不是原始 json...
    • React 应用程序之前也一直在发送 json 请求(到 Song 端点),所以现在当我再次收到 Bad Requests 时,我意识到出了点问题。 (因为我是用邮递员测试的,所以我构建了期望 formdata 的新视图)无论如何,关键是你不可能知道这个问题,因为我从来没有谈论过那部分,因为我认为那里不会有问题。如果其他人有类似的问题,如果您使用 Django REST Framework,请确保您的请求以原始 json 格式发送。