I want to be able to update a user's password in my React.js and Django app

Backend is Dango The front end is made with React.js.

What I want to achieve it I want to users to update their registered passwords.

Issue/error message

If you update the password on the React.js side, it will look like the following and the update will fail. .

enter image description here

Django side Terminal

{'password': 'welcome1313'}
username
{'detail': [ErrorDetail(string='Invalid data. Expected a dictionary, but got str.', code='invalid')]}
Bad Request: /users/12/
[15/Jan/2023 15:42:10] "PATCH /users/12/ HTTP/1.1" 400 13

React.js

    const MyPagePasswordUpdate = () => {
      const [my_password, setValue] = useState(null);
      const [my_ID,setMyID] = useState(null);
      const isLoggedIn= useSelector(state => state.user.isLoggedIn);
    
      const { register, handleSubmit, errors } = useForm();
    
      useEffect(() => {
        async function fetchData(){
          const result = await axios.get(
            apiURL+'mypage/',
            {
              headers: {
                  'Content-Type': 'application/json',
                  'Authorization': `JWT ${cookies.get('accesstoken')}`
                }
            })
            .then(result => {
              setValue(result.data.password);
              setMyID(result.data.id);
            })
            .catch(err => {
              console.log("err");
            });
        }
      

fetchData();
  },[]);


const update = async (data) =>{
      console.log(data)
      await axios.patch(`${apiURL}users/`+my_ID+'/',
        {

          headers: {
            'Content-Type': 'application/json',
            'Authorization': `JWT ${cookies.get('accesstoken')}`
          },
          password:data.password,
        },
      ).then(message => {
        alert("Updated!")
      })
      .catch(err => {
          console.log("miss");
          alert("The characters are invalid");
      });
    };

  return (
    <div>
      {isLoggedIn ?
        <div class="update-block">
          <form onSubmit={handleSubmit(update)}>
          <label for="password">Password:</label>
          <input className='form-control' type="password" {...register('password')} />
          <input className='btn btn-secondary' type="submit" value="Update" />
          </form>
          <Link to="/mypage">Back to My Pgae</Link>
        </div> :
        <div>
              Logout
        </div>
      }

    </div>
  )
};

export default MyPagePasswordUpdate;

views.py

class UserViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.UpdateOwnProfile,)
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def update(self, request, pk, partial=True):
            user = User.objects.get(id=pk)
            if request.data['password']:
                data = request.data['password']
                serializer = self.serializer_class(user,data=data, partial=True)
                if user.is_anonymous:
                    return Response("unauthorized", status=status.HTTP_401_UNAUTHORIZED)
                if serializer.is_valid():
                    serializer.save()
                return Response("bad request", status=status.HTTP_400_BAD_REQUEST)

            else:
                data={'state': request.data['state'], 'city': request.data['city'], 'address': request.data['address'], 'zipcode': request.data['zipcode'],'phone_number': request.data['phone_number']}
                if request.data['username'] != user.username:
                    data['username'] = request.data['username']
                if request.data['email'] != user.email:
                    data['email'] = request.data['email']

            
            serializer = self.serializer_class(user,data=data, partial=True)
  
            if user.is_anonymous:
                return Response("unauthorized", status=status.HTTP_401_UNAUTHORIZED)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_200_OK)
            print(serializer.errors)
            return Response("bad request", status=status.HTTP_400_BAD_REQUEST)

models.py

class User(AbstractUser):
    email = models.EmailField(blank=True, max_length=254, unique=True, verbose_name='email address')
    state = models.ForeignKey(State,verbose_name='State', on_delete=models.CASCADE, blank=True, null=True)
    city = models.CharField(verbose_name='City', max_length=20, blank=True, null=True)
    address = models.CharField(verbose_name='Address', max_length=50, blank=True, null=True)
    zipcode = models.CharField(verbose_name='Zip Code',max_length=10, blank=True, null=True)
    phone_number = PhoneField(verbose_name='Phone Number ',blank=True, null=True)
    objects = CustomUserManager()

serializers.py

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)

    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'password', 'state', 'city', 'address', 'zipcode', 'phone_number')
        
    def create(self,validated_data):
            user = User.objects.create_user(
                email=validated_data['email'],
                username=validated_data['username'],
                password=validated_data['password'],
            )
            print(validated_data)
            return user

    def update(self,instance,validated_data):
        if 'password' in validated_data:
            password=validated_data.pop('password')
            instance.set_password(password)       

        return super().update(instance,validated_data)
const update = async (data) =>{
      console.log(data)
      await axios.patch(`${apiURL}users/`+my_ID+'/',
        {

          headers: {
            'Content-Type': 'application/json',
            'Authorization': `JWT ${cookies.get('accesstoken')}`
          },
          password:data.password,
        },
      ).then(message => {
        alert("Updated!")
      })
      .catch(err => {
          console.log("miss");
          alert("The characters are invalid");
      });
    };

There's a problem with how you're constructig your axios requests. It should be .patch(url, data, config)

like this

url = `${apiURL}users/${my_ID}/`;
data = {password: data.password};
config = { headers: { 'Content-Type': 'application/json', 'Authorization': `JWT ${cookies.get('accesstoken')}` }}
await axios.patch(url, data, config);
Back to Top