0

I am using a updateapiview to the update my user information. This is my view

class UserUpdateView(generics.UpdateAPIView):
   serializer_class = UserUpdateSerializer

  def get_queryset(self):
    print(self.kwargs['pk'])
    return User.objects.filter(pk=self.kwargs['pk'])

  def partial_update(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data, partial=True)
    if self.get_object() != request.user:
        return Response({'error': 'permission denied'}, status=status.HTTP_400_BAD_REQUEST)
    print(request.data['password'])
    request.data['password'] = make_password(request.data['password'])
    instance = super(UserUpdateView, self).partial_update(request, *args, **kwargs)
    return instance

This is my serializer

class UserUpdateSerializer(serializers.ModelSerializer):

  email = serializers.EmailField(required=True)

  def validate_username(self, username):
    if User.objects.filter(username=username):
        raise serializers.ValidationError('Username already exists!!')
    return username

  def validate_email(self, email):
    if User.objects.filter(email=email):
        raise serializers.ValidationError('Email already exists!!')
    return email

  class Meta:
    model = User
    fields = ('pk', 'username', 'password', 'email')
    read_only_fields = ('pk',)

I am getting the data updated and returned successfully. But I want to add some field like message with content 'successfully updated' on successful updation of the user profile. I searched if there is any way to perform this but can't find the appropriate way to do it (alike get_context_data method in django). So, is there any way to perform the above task ??

Question 2: How to prevent the self user ( i.e if has a email [email protected] and if user clicks udpate with the same email, it should not raise an error that username already exists, I guess this can be done with self.instance (but not sure how actually to implement it).

Thanks!

1 Answer 1

1

I'm not sure what version of DRF you are using but in the latest 3.9.0 UpdateAPIView uses UpdateModelMixin, which returns Response object instead of instance. So you can modify data before returning.

def partial_update(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data, partial=True)
    if self.get_object() != request.user:
        return Response({'error': 'permission denied'}, status=status.HTTP_400_BAD_REQUEST)
    print(request.data['password'])
    request.data['password'] = make_password(request.data['password'])
    response = super(UserUpdateView, self).partial_update(request, *args, **kwargs)
    response.data['message'] = 'Successfully updated'
    return response

Regarding your second question you can exclude the current user using self.instance.

def validate_email(self, email):
    if User.objects.filter(email=email).exclude(id=self.instance.id).exists():
        raise serializers.ValidationError('Email already exists!!')
    return email
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @UnholyRaven

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.