PUT metod делает поле пароля обязательным, и когда я ввожу значение в поле, оно сохраняется как текст в базе данных без хэша

views.py

from .serializers import CreateUser,ShowUser,MeSerializer,ChangePasswordSerializer
from rest_framework import viewsets
from django.contrib.auth.models import User
from rest_framework.decorators import action
from rest_framework.response import Response

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    create_serializer_class = CreateUser
    show_serializer_class = ShowUser
    # serializer_class = ChangePasswordSerializer

    
    def get_serializer_class(self):
        if self.action in ["list","retrieve"]:
            return self.show_serializer_class
        if self.action in ["partial_update","destroy","create","update"]:
            return self.create_serializer_class
        
        return self.serializer_class
        
    @action(detail=False,serializer_class=MeSerializer)
    def me(self, request):
        self.kwargs["pk"] = request.user.pk
        return super().retrieve(request)
    
    @action(methods=['put'],detail=True,serializer_class=ChangePasswordSerializer ,url_path="change-password")
    def change_password(self,request,pk=None):
        super().update(request)
        return Response({
            "stats" : "Password Changed"
        })

serializers.py

from rest_framework import serializers
from django.contrib.auth.models import User

class CreateUser(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
confirm_password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = [
"username",
'first_name',
'last_name',
'email',
'password',
'confirm_password'
]

    def validate(self, data):
        password = data.get('password')
        confirm_password = data.get('confirm_password')
        if password != confirm_password:
            raise serializers.ValidationError("The password must match")
        else:
            return data
    
    def create(self, validated_data):
        user = User.objects.create(
            username=validated_data.get('username'),
            first_name=validated_data.get("first_name"),
            last_name= validated_data.get("last_name"),
            email= validated_data.get("email")
            )
        user.set_password(validated_data.get("password"))
        user.save() 
        return user

class ShowUser(serializers.ModelSerializer):
class Meta:
model = User
exclude = [
'password'
]

class MeSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
"id",
"username",
"first_name",
'last_name',
'email',
]

class ChangePasswordSerializer(serializers.ModelSerializer):
old_password = serializers.CharField(write_only=True)
new_password = serializers.CharField(write_only=True)
new_password_confirmation = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = [
            'old_password',
            'new_password',
            'new_password_confirmation'
        ]
        
    def validate_old_password(self, value):
        user = self.context["request"].user
        if not user.check_password(value):
            raise serializers.ValidationError("Old password is incorrect.")
        return value
    
    def validate(self, attrs):
        if attrs['new_password'] != attrs['new_password_confirmation']:
            raise serializers.ValidationError("New passwords do not match.")
        return attrs
    
    def update(self, instance, validated_data):
        instance.set_password(validated_data['new_password'])
        instance.save()
        return instance

когда я перехожу к http://127.0.0.1:8000/api/user/5/ с помощью метода PUT, поля password и confirm_password становятся обязательными, и когда я ввожу значение в поля, оно сохраняется в виде текста в базе данных без хэша. и когда я пытаюсь войти в систему с этим открытым текстовым паролем (после метода PUT), пароль не принимается изображение проблемы но когда метод PUTCH поля password и confirm_password НЕ обязательны и это делает chnge

Почему это происходит и как это можно исправить

я пытаюсь найти проблему в сериализаторах и не могу ее найти

Вы собираетесь обновить пароль экземпляра, ссылка на документацию: https://www.django-rest-framework.org/api-guide/serializers/

def update(self, instance, validated_data):
    new_password = validated_data.pop('new_password', None)
    if new_password:
        instance.set_password(new_password)
    instance.save()
    return instance
Вернуться на верх