1

I'm trying to write a create method that will write my nested fields but am finding that the nested object isn't written.

This is the sample I was using:

class UserSerializer(serializers.ModelSerializer):
 profile = ProfileSerializer()
 class Meta:
 model = User
 fields = ('username', 'email', 'profile')
 def create(self, validated_data):
 profile_data = validated_data.pop('profile')
 user = User.objects.create(**validated_data)
 Profile.objects.create(user=user, **profile_data)
 return user

But I'm failing to understand what the user=user refers to.

Here is my code:

class MessagesSerializer(serializers.HyperlinkedModelSerializer):
 id = serializers.IntegerField(source='pk', read_only=True)
 suggested_songs = SongSerializer()
 class Meta:
 model = Messages
 fields = ('id','owner','url','suggested_songs',)
 #fields = ('id','url','suggested_songs',)
 def create(self, validated_data):
 song_data = validated_data.pop('suggested_songs')
 message = Messages.objects.create(**validated_data)
 Song.objects.create(**song_data)
 return message
class SongSerializer(serializers.HyperlinkedModelSerializer):
 #id = serializers.IntegerField(source='pk', read_only=True)
 class Meta:
 model = Song
 fields = ('id','title','artist','album','albumId','num_votes','cleared')
 read_only_fields = ('song_id')
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.ManyToManyField(Song, related_name='suggested_songs')
 suggested_songs = models.ForeignKey(Song, null=True, blank=True)
 # If a user is added, this runs. 
 @receiver(post_save, sender=User)
 def create_friend_for_user(sender, instance=None, created=False, **kwargs):
 if created:
 Messages.objects.get_or_create(owner=instance)
 # Same as above, but for deletion 
 @receiver(pre_delete, sender=User)
 def delete_friend_for_user(sender, instance=None, **kwargs):
 if instance:
 Messages.objects.get(owner=instance).delete()
class Song(models.Model):
 """
 A model which holds information about the songs.
 """
 #song_id = models.IntegerField(primary_key=True)
 title = models.CharField(max_length=150, blank=True, default='')
 artist = models.CharField(max_length=150, blank=True, default='')
 album = models.CharField(max_length=150, blank=True, default='')
 albumId = models.CharField(max_length=150, blank=True, default='')
 num_votes = models.IntegerField(default=0, blank=True)
 cleared = models.BooleanField(default=False, blank=True)
 class Meta:
 ordering = ('title',)
 #managed=True
asked May 3, 2015 at 11:26
1
  • You mean that the Song and Messages objects are created but not linked together or the Song is not created at all? Commented May 3, 2015 at 11:35

1 Answer 1

3

I think that the issue might be in the MessageSerializer.create method:

def create(self, validated_data):
 # here you are popping the suggested songs
 song_data = validated_data.pop('suggested_songs')
 # so when you create the message here the foreign key is set to NULL
 message = Messages.objects.create(**validated_data)
 # and here you create the Song instance correctly but it is not
 # associated with the message
 Song.objects.create(**song_data)
 return message

You need to pass the foreign key to the Messages.create method like in the example you have.

def create(self, validated_data):
 song_data = validated_data.pop('suggested_songs')
 song = Song.objects.create(**song_data)
 # song need to be created first because the foreign key is in
 # the Messages model
 message = Messages.objects.create(suggested_songs=song, **validated_data)
 return message

I hope this helps!

answered May 3, 2015 at 11:48
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.