mardi 5 mai 2015

How do I write a Django rest framework writeable nested serializer by overriding onCreate? (with manyToMany relationship)

I am trying to write a serializer within the django rest framework that has a manyToMany relationship. I want the serializer to be writeable so I can send data to the object and am trying to override the create method to achieve this but am running into problems.

I can't find any examples which implement this particular behaviour.

Models:

class Messages(models.Model):
    owner = models.OneToOneField(User, primary_key=True, related_name='user_messages', editable=False) #TODO, change owner to 'To'
    #suggested_songs = models.ForeignKey(Song, null=True, blank=True)
    suggested_songs = models.ManyToManyField(Song, related_name='suggested_songs',null=True, blank=True)

Serializers:

class MessagesSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.IntegerField(source='pk', read_only=True)
    suggested_songs = SongSerializer(many=True)

    class Meta:
        model = Messages
        fields = ('id','owner','url','suggested_songs',)

def create attempts:

def create(self, validated_data):
    song_data = validated_data.pop('suggested_songs')
    messages = Messages.objects.create(**validated_data)
    for song in song_data:
        s = Song.objects.create()
        s.song = song.get("song")
        s.save()
        messages.suggested_songs.add(s)
    #post.save()
    return message

Produces the error:

"" needs to have a value for field "messages" before this many-to-many relationship can be used. So I can't create messages without first making "suggested_songs".

So I attempted the following:

def create(self, validated_data):
    suggested_songs_data = validated_data.pop('suggested_songs')
    suggest_song_list = list()
    for song_data in suggested_songs_data:
        song = Song.objects.create(**song_data)
        suggest_song_list.append(song)          
    message = Messages.objects.create(suggested_songs=suggest_song_list, **validated_data)
    return message

Produces: 'suggested_songs' is an invalid keyword argument for this function. I'm guessing because I've built the object incorrectly?

I am also trying to override "def update" next so an example with that also would be great.

Aucun commentaire:

Enregistrer un commentaire