Luka Reeson
Luka Reeson

Reputation: 123

Djago rest framework - username/email already exsists when trying to update user info

I'm trying to update user info with a serializer, but even if I don't change the user's username or email when submitting, I get the validating error mention in the title. I just want to update info like the first name for example, but if I change its user name into an already existing one, then I want the error to pop up.

Serializer.py

class UpdateUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserAccount
        fields = ['username', 'email', 'first_name', 'last_name', 'about', 'password']
        extra_kwargs = {"password": {"write_only": True}}

    def validate_password(self, value):
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError('Incorrect Password')

    
    def update(self, instance, validated_data):
        instance.username = validated_data.get("username", instance.username)
        instance.email = validated_data.get("email", instance.email)
        instance.first_name = validated_data.get("first_name", instance.first_name)
        instance.last_name = validated_data.get("last_name", instance.last_name)
        instance.about = validated_data.get("about", instance.about)
        
        instance.save()
        return instance

Views.py

@api_view(['PATCH'])
@permission_classes([IsAuthenticated])
def update_user(request):
    if request.method == 'PATCH':
        user = request.user
        serializer = UpdateUserSerializer(data=request.data, context={'request': request})
        data = {}
        if serializer.is_valid():
            user = serializer.update(user, request.data)
            data['user'] = UserSerializer(user).data
        else:
            data = serializer.errors
        return Response(data)

Upvotes: 1

Views: 597

Answers (1)

Brian Destura
Brian Destura

Reputation: 12068

You have to pass the instance to UpdateUserSerializer when initializing it, otherwise is_valid() will think that you are creating a new object, hence the error.

So you can do something like:

@api_view(['PATCH'])
@permission_classes([IsAuthenticated])
def update_user(request):
    if request.method == 'PATCH':
        user = request.user
        serializer = UpdateUserSerializer(
            data=request.data, instance=user, context={'request': request}
        )

        data = {}

        if serializer.is_valid():
            user = serializer.save()
            data['user'] = UserSerializer(user).data
        else:
            data = serializer.errors
        return Response(data)

save() will call update() for you when there is an instance in the serializer so no need to explicitly call it.

Upvotes: 1

Related Questions