Deep3015 Deep3015 - 1 month ago 5
Python Question

How to combine fields of two different model and create ModelSerializer

I have two models CustomUser and UserProfile.

class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), max_length=254, unique=True, blank=True)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)

class UserProfile(models.Model):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
owner_of = models.CharField(max_length=100, blank=True)
total_years= models.CharField(_('In Current Profession Since'),max_length=100,blank=True, null=True)


serializers.py:

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
fields = ('id', 'email','first_name', 'last_name',)

class ProfileSerializer(serializers.ModelSerializer):
user = AccountSerializer(read_only=True,required=False)
class Meta:
model = UserProfile
fields = ('user','owner_of','total_years','first_name','last_name','email')


Error I get
"Field name
first_name
is not valid for model
UserProfile
."

How to combine two model fields and make create and update function

Answer

Your profileserializer should be like this,

class ProfileSerializer(serializers.ModelSerializer):
    user = AccountSerializer(required=True)
    class Meta:
        model = UserProfile
        fields=('user','owner_of','total_years')

which results like this,

{
    {
        "user":
         {
               "id: ...,
               "first_name": ...,
               "last_name": ...,
               "email": ...
          },
          "owner_of": ...,
          "total_years" ...
     },
     ...
}

More detailed explanation is here.

By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create create() and/or update() methods in order to explicitly specify how the child relationships should be saved.

class ProfileSerializer(serializers.ModelSerializer):
    user = AccountSerializer(required=True)
    class Meta:
        model = UserProfile
        fields=('user','owner_of','total_years')

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user= CustomUser.objects.create(**user_data)
        user_profile=UserProfile.objects.create(user=user, **validated_data)
        return user_profile

    def update(self, instance, validated_data):
        user_data = validated_data.pop('user', None)
        user = instance.user
        instance.owner_of = validated_data.get("owner_of", instance.owner_of)
        instance.total_years= validated_data.get("total_years", instance.total_years)
        instance.save()
        if user_data:
            user.first_name = user_data.get("first_name", user.first_name)
            user.last_name = user_data.get("last_name", user.last_name)
            user.email= user_data.get("email", user.email)
            user.save()
Comments