使用序列化程序作为字段时,无法更新m2m

mar*_*rwy 4 python django django-rest-framework

我有以下型号:

class Song(models.Model):
    name = models.CharField(max_length=64)

    def __unicode__(self):
        return self.name

class UserProfile(AbstractUser):
    current = models.ManyToManyField(Song, related_name="in_current", blank=True)
    saved = models.ManyToManyField(Song, related_name="in_saved", blank=True)
    whatever = models.ManyToManyField(Song, related_name="in_whatever", blank=True)

    def __unicode__(self):
        return self.get_username()
Run Code Online (Sandbox Code Playgroud)

以及序列化器:

class SongSerializer(serializers.ModelSerializer):
    class Meta:
        model = Song

class UserProfileSongsSerializer(serializers.ModelSerializer):
    current = SongSerializer(many=True)
    saved = SongSerializer(many=True)
    whatever = SongSerializer(many=True)

    class Meta:
        model = UserProfile
        fields = ("id", "current", "saved", "whatever")
Run Code Online (Sandbox Code Playgroud)

并且我正在使用UpdateAPIView:

class UserProfileSongsUpdate(generics.UpdateAPIView):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSongsSerializer
Run Code Online (Sandbox Code Playgroud)

问题:我无法将歌曲(即使它已经存在于数据库中)添加到任何(当前,已保存,无论如何),我只能删除它.

curl -X PUT -d '{"current": [{"id": 1, "name": "sialalalal"}, {"id": 2, "name": "imissmykitty"}], "saved": [{"id": 3, "name": "kittyontheroad"}], "whatever": []}' -H "Content-Type:application/json" localhost:8000/userprofile/1/songs/update/
Run Code Online (Sandbox Code Playgroud)

这将删除当前集合中的所有其他歌曲(这很好:)),但是当我尝试将现有歌曲添加到当前集合时,它将显示错误:

curl -X PUT -d '{"current": [{"id": 1, "name": "sialalalal"}, {"id": 2, "name": "imissmykitty"}, {"id": 7, "name": "vivalakita"}], "saved": [{"id": 3, "name": "kittyontheroad"}], "whatever": []}' -H "Content-Type:application/json" localhost:8000/userprofile/1/songs/update/
Run Code Online (Sandbox Code Playgroud)

我明白了:

{"current": [{}, {}, {"non_field_errors": ["Cannot create a new item, only existing items may be updated."]}]}
Run Code Online (Sandbox Code Playgroud)

但!如果我删除序列化字段:

class UserProfileSongsSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields = ("id", "current", "saved", "whatever")
Run Code Online (Sandbox Code Playgroud)

我这样做:

curl -X PUT -d '{"current": [1, 2, 7], "saved": [3], "whatever": []}' -H "Content-Type:application/json" localhost:8000/userprofile/1/songs/update/
Run Code Online (Sandbox Code Playgroud)

它添加了没有任何问题的歌曲......

我可以添加和删除当前集合中的歌曲,并使用序列化程序作为字段保存吗?

alm*_*lki 7

是的你可以.你需要设置allow_add_removeTrueread_onlyFalse:

current = SongSerializer(many=True, allow_add_remove=True, read_only=False)
Run Code Online (Sandbox Code Playgroud)

请注意,嵌套序列化程序的当前实现将从DB中删除整个Song对象,而不仅仅是关系.