0
votes

I have a Profile model which after user signs up has to update their profile. For that i have designed two serializer, one UserSerializer to show the list of users and another ProfileSerializer which has lots of fields for user to add in their profile. The user not only gets to update their profile like height, weight, age, location, body_type etc but also should get to update first_name, last_name, email from the profile.

Here is my UserSerializer and ProfileSerializer

class ProfileSerializer(serializers.ModelSerializer):
    # url = serializers.HyperlinkedRelatedField(source="user", view_name="user_profile")
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    token = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Profile
        fields = ('token', 'user', 'current_location', 'permanent_location', 'dob',
                    'about_me', 'gender_status', 'create_profile_for', 'marital_status',
                    'height', 'weight', 'body_type', 'complexion',)

    def update(self, instance, validated_data):
        first_name = validated_data.pop('first_name', None)
        last_name = validated_data.pop('last_name', None)
        user_inst_fields = {}
        if first_name:
            user_inst_fields['first_name'] = first_name
        if last_name:
            user_inst_fields['last_name'] = last_name
        if user_inst_fields:
            User.objects.update_or_create(id=instance.user.id, defaults=user_inst_fields)
        profile, created = Profile.objects.update_or_create(token=instance.token, defaults=validated_data)
        print('profile', profile, created)
        return profile

class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(required=True)
    class Meta:
        model = User
        fields = ('id', 'profile', 'username', 'email', 'first_name', 'last_name',)

I could not show the fields of first_name, last_name and username for user to update them along with their profile.

You can see the screenshot, no first_name, last_name and username is shown

enter image description here

1

1 Answers

1
votes

You show the first_name , last_name and username in ProfileSerializer using source keyword argument in a CharField for first_name and last_name and username.

class ProfileSerializer(serializers.ModelSerializer):
    # url = serializers.HyperlinkedRelatedField(source="user", view_name="user_profile")
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    token = serializers.PrimaryKeyRelatedField(read_only=True)
    first_name = serializers.CharField(source = "user.first_name")
    last_name = serializers.CharField(source = "user.last_name")
    username = serializers.CharField(source = "user.username")

    class Meta:
        model = Profile
        fields = ('token', 'user', 'current_location', 'permanent_location', 'dob',
                    'about_me', 'gender_status', 'create_profile_for', 'marital_status',
                    'height', 'weight', 'body_type', 'complexion',)

    def update(self, instance, validated_data):
        first_name = validated_data.pop('first_name', None)
        last_name = validated_data.pop('last_name', None)
        user_inst_fields = {}
        if first_name:
            user_inst_fields['first_name'] = first_name
        if last_name:
            user_inst_fields['last_name'] = last_name
        if user_inst_fields:
            User.objects.update_or_create(id=instance.user.id, defaults=user_inst_fields)
        profile, created = Profile.objects.update_or_create(token=instance.token, defaults=validated_data)
        print('profile', profile, created)
        return profile

Now , DRF will fetch first_name , last_name and email from the user relation on the Profile model.