当使用序列化程序作为字段时,无法更新m2m [英] Updating m2m not possible when using serializers as fields

查看:119
本文介绍了当使用序列化程序作为字段时,无法更新m2m的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下模型:

  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()

和以下序列化程序:

  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)

并且正在使用UpdateAPIView:

  class UserProfileSongsUpdate(generics.UpdateAPIView):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSongsSerializer

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

  curl -X PUT -d'{current:[{id:1,name:sialalalal},{id:2,name :imissmykitty}],保存:[{id:3,name:kittyontheroad}],whatever:[]}'-HContent-Type:application / jsonlocalhost: 8000 / userprofile / 1 / songs / update / 

这将删除所有其他歌曲>当前集合(这很好:)),但是当我尝试将已经存在的歌曲添加到当前的集合会显示一个错误:

  curl -X PUT -d'{current:[{id name:sialalalal},{id:2,name:imissmykitty},{id:7,name:vivalakita}],saved:[{id :3,name:kittyontheroad}],whatever:[]}'-HContent-Type:application / jsonlocalhost:8000 / userprofile / 1 / songs / update / 

我得到:

  {current:[{},{},{non_field_errors:[无法创建新项目,只有现有项目可能会更新。]}}} 
/ pre>

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

  class UserProfileSongsSerializer(serializers.ModelSerializer):

class Meta:
model = UserProfile
fields =(id,current,saved,whatever)

我做:

  curl -X PUT -d'{current:[1 ,2,7],saved:[3],whatever:[]}'-HContent-Type:application / jsonlocalhost:8000 / userprofile / 1 / songs / update / 

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



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

解决方案

是的,你可以。你需要将 allow_add_remove 设置为 True read_only code> False :

  current = SongSerializer(many = True,allow_add_remove = read_only = False)

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


I have following models:

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()

and following serializers:

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")

and am using UpdateAPIView as such:

class UserProfileSongsUpdate(generics.UpdateAPIView):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSongsSerializer

The problem: I can't add a song (even if it already exists in the DB) to any of (current, saved, whatever), I can only remove it.

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/

This will remove all of the other songs in current collection (that's good :)), but when I'll try to add already existing song to the current collection it will show me an error:

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/

I get:

{"current": [{}, {}, {"non_field_errors": ["Cannot create a new item, only existing items may be updated."]}]}

BUT! if I remove serializers fields:

class UserProfileSongsSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields = ("id", "current", "saved", "whatever")

and I do:

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

it adds the song without any issues...

Can I add and remove songs from collections like current and saved using serializers as fields?

解决方案

Yes you can. you need to set allow_add_remove to True and read_only to False:

current = SongSerializer(many=True, allow_add_remove=True, read_only=False)

Note that the current implementation of nested serializers will remove the whole Song object from DB, not only the relation.

这篇关于当使用序列化程序作为字段时,无法更新m2m的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆