Reputation: 123
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
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