bsmith4
bsmith4

Reputation: 97

Django Rest Framework - Check Password to Validate Form

I'm trying to validate a form through DRF, but it would require the user to enter their password for confirmation. I can't seem to get it to work. Here is my current View and Serializer. Its for a 'change email' form, two fields required, the email and user password. It's for a seperate email model. The serializer:

class UpdateEmailAddressSerializer(serializers.ModelSerializer):

    class Meta:
        model = EmailAddress
        fields = ('email',)

And the APIView:

class UpdateEmailAPI(APIView):

permission_classes = (IsAuthenticated,)
serializer_class = UpdateEmailAddressSerializer

def post(self, request, user, format=None):
    user = User.objects.get(username=user)
    serializer = UpdateEmailAddressSerializer(data=request.data, instance=user)
    if serializer.is_valid():

        ## logic to check and send email

        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)  

I'm not sure where to place the password or what to do with it. Its from the User model itself. When I attempted to add password to the fields in the UpdateEmail serializer it ended up updating the User password with plain text and making that user object unable to use that password.

I just want to check the password of the user for confirmation of this form. Is there an obvious way to do this?

EDIT

When I attempt to bring 'password' into the serializer, an error tells "Field name password is not valid for model EmailAddress." So when I attempt to bring it in e.g.

password = serializers.CharField(required=True)

or try:

## UserPasswordSerializer 
class UserPasswordSerializer(serializers.ModelSerializer):

class Meta:
    model = User
    fields = (
        'password',
        )

## In UpdateEmailAddressSerializer
password = UserPasswordSerializer()

I get this error when submitting the form on DRF:

Got AttributeError when attempting to get a value for field password on serializer UpdateEmailAddressSerializer. The serializer field might be named incorrectly and not match any attribute or key on the EmailAddress instance. Original exception text was: 'EmailAddress' object has no attribute 'password'

So it seems to be telling me password isn't part of EmailAddress model which is correct. But I cant figure out how to simply check the password alongside the form post without making it part of EmailAddress.

Upvotes: 2

Views: 5304

Answers (1)

ruddra
ruddra

Reputation: 51938

I think you can try like this:

class UpdateEmailAddressSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    class Meta:
        model = EmailAddress
        fields = ('email', 'password',)

    def create(self, validated_data):
       validated_data.pop('password', None)
       return super(UpdateEmailAddressSerializer, self).create(validated_data)

    def update(self, instance, validated_data):
         if instance.check_password(validated_data.get('password')):
               instance.email = validated_data.get('email', instance.email)
         # else throw validation error
         return instance

Upvotes: 1

Related Questions