Django Rest Framework: validate_username and update methods not called during PUT request

I am working on a Django Rest Framework (DRF) project, where I need to validate a username field and handle custom update logic in a serializer. My model has a username field with unique=True. Here's the relevant setup:

Model:


from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    pass

Serializer:

class CustomUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.CustomUser
        fields = ["id", "username", "first_name", "last_name"]
        read_only_field = ["id"]
        extra_kwargs = {
            "password": {"write_only": True},
        }

    def validate_username(self, value):
        print('here.......')
        user_model = get_user_model()
        request = self.context.get('request')  
        if request and request.method in ['PUT', 'PATCH']:
            
            if user_model.objects.filter(username=value).exclude(id=self.instance.id).exists():
                raise serializers.ValidationError('User with this username already exists.')
        else:
            if user_model.objects.filter(username=value).exists():
                raise serializers.ValidationError('User with this username already exists.')
        return value


class CustomUserProfileSerializer(serializers.ModelSerializer):
    user = CustomUserSerializer()
    roles = ProfileRolesSerializer(many=True)
    department = DepartmentSerializer()
    gender = GenderSerializer()

Views:


class CustomUpdateView(APIView):
    def put(self, request, *args, **kwargs):
        serializer = CustomUserProfileSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

When I send a PUT request to update a user profile, the validate_username and update methods in the serializer are not executed. Instead, I get a response error:

{
    "user": {
        "username": [
            "User with this username already exists."
        ]
    }
}

I suspect that the default unique=True constraint on the username field is bypassing the serializer-level validation. I have tried:

  1. Adding print statements in validate_username and update methods — these are never executed.
  2. Switching to a custom APIView (CustomUpdateView) — no change.
  3. Ensuring CustomUserProfileSerializer is correctly used in the view.

What could be causing this issue, and how can I ensure that the validate_username and update methods are called during a PUT request?

You should avoid nesting CustomUserSerializer inside CustomUserProfileSerializer.

Instead, handle the user field separately in the update method of CustomUserProfileSerializer. Additionally, move the username validation logic from CustomUserSerializer to CustomUserProfileSerializer to ensure proper handling of updates.

Back to Top