Django Rest - Serializer: must be a instance on create

I'm trying to create create a nested serializer using the Django Rest framework. The relationship is Profile X User but when i use Profile.objects.create(user=profile, **user_data) i get ValueError: Cannot assign "<Profile: Profile object (7)>": "Profile.user" must be a "User" instance..

This should be some rookie misunderstanding of models relationship definitions or the serializer declaration itself but I can't find anything around the docs. If someone can point me a direction I'll be gracefull.

models.py

class User(models.Model):
    name = models.CharField(max_length=100, blank=False)
    email = models.CharField(max_length=100, blank=True, default='')
    password = models.CharField(max_length=100, blank=True, default='')
    timestamp = models.DateTimeField(default= timezone.now)

    class Meta:
        ordering = ['timestamp']

class Profile(models.Model):

    # choices [...]

    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
    profile_type = models.CharField(max_length=2,choices=PROFILE_CHOICES,default=TEAMMEMBER)
    authentication_token  = models.CharField(max_length=100,  null=True)
    avatar_url  = models.CharField(max_length=100, default='')
    permissions = models.CharField(max_length=100, null=True)
    timestamp = models.DateTimeField(default= timezone.now)

    class Meta:
        ordering = ['timestamp']

serializer.py

class UserSerlializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['name', 'email', 'password']

class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerlializer()

    class Meta:
        model = Profile
        fields = ['user', 'profile_type']

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        profile = Profile.objects.create(**validated_data)
        Profile.objects.create(user=profile, **user_data)
        return Profile

POST

{   
    "profile_type" : "ST",
      "user": {
        "name" : "test",
        "email" : "[email protected]",
        "password" : "123456"
    }
}

Upvotes: 1

Views: 2931

Answers (3)

bmons
bmons

Reputation: 3392

inherit your user model from django contrib auth module also, and make a one to one relation with profile

from django.contrib.auth.models import User

Upvotes: 0

JPG
JPG

Reputation: 88529

You are creating instances in wrong way. Change your create(...) method as,

class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerlializer()

    class Meta:
        model = Profile
        fields = ['user', 'profile_type']

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user_instance = User.objects.create(**user_data)
        profile_instance = Profile.objects.create(user=user_instance, **validated_data)
        return profile_instance

Upvotes: 4

Nalin Dobhal
Nalin Dobhal

Reputation: 2342

Profile.user should beUser instance, but you are assigning Profile instance.

Change your create method to this:

class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerlializer()

    class Meta:
        model = Profile
        fields = ['user', 'profile_type']

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        profile = Profile.objects.create(**validated_data)
        user = User.objects.create(**user_data) # 1. creating user
        profile.user = user # 2. assigning user
        profile.save()  # 3. saving profile after adding user
        return profile # returning Profile instance.

Upvotes: 0

Related Questions