Sandesh Ghanta
Sandesh Ghanta

Reputation: 405

Django rest framework add extra context in response

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!

Upvotes: 0

Views: 1207

Answers (1)

UnholyRaven
UnholyRaven

Reputation: 407

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

Upvotes: 1

Related Questions