2

I'm writing a custom user authentication for an app based on the Thinkster IO tutorial here: https://thinkster.io/django-angularjs-tutorial/

I've tweaked the user creation to use a confirmed password and then doing the save.

I thought I had everything working well, but I'm getting stuck on one error.

I believe that this is the problem code.

def create(self, validated_data):
    # get the password or leave it alone
    password = validated_data.get('password', None)
    # get the confirm_password or leave it alone
    confirm_password = validated_data.get('confirm_password', None)

    # If the password exists AND the confirm password exists AND they eaqual each other
    if password and confirm_password and password == confirm_password:
        # create the object with valid form data
        return models.Account.objects.create(**validated_data)

The error is: 'confirm_password' is an invalid keyword argument for this function

And it looks like it's being triggered by my view for the API. Any thoughts in why this is happening? It seems to me that this shouldn't be an issue as the check is in the view BEFORE the save and it just uses the password if it matches.

Any help would be great.

Here is the complete serializer

from django.contrib.auth import update_session_auth_hash

from rest_framework import serializers

from . . import models


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

    class Meta:
        model = models.Account
        fields = ('id', 'email', 'username', 'created_at', 'updated_at',
                  'first_name', 'last_name', 'password',
                  'confirm_password',)
        read_only_fields = ('created_at', 'updated_at',)

        def create(self, validated_data):
            # get the password or leave it alone
            password = validated_data.get('password', None)
            # get the confirm_password or leave it alone
            confirm_password = validated_data.get('confirm_password', None)

            # If the password exists AND the confirm password exists AND they eaqual each other
            if password and confirm_password and password == confirm_password:
                # create the object with valid form data
                return models.Account.objects.create(**validated_data)

        def update(self, instance, validated_data):
            # get the username, if not changed that use the instance username
            instance.username = validated_data.get('username', instance.username)
            # update the instance
            instance.save()
            # get the password or leave it alone
            password = validated_data.get('password', None)
            # get the confirm_password or leave it alone
            confirm_password = validated_data.get('confirm_password', None)

            # If the password exists AND the confirm password exists AND they eaqual each other
            if password and confirm_password and password == confirm_password:
                # create the password with the password submitted
                instance.set_password(password)
                #save that instance with the updated password
                instance.save()

            # update the session so that the user does not need to login again
            update_session_auth_hash(self.context.get('request'), instance)

            # return the changed (or not changed) record
            return instance

1 Answer 1

5

It looks like the way you save the data in your Account model is incorrect.

first, do you have a confirm_password field in your Account model? (i believe you don't and that is the meaning of the error)

Solution:

# use .pop() instead of .get() so that it will be removed from the dict
# `None` to avoid KeyError. so pop the value if it exists
confirm_password = validated_data.pop('confirm_password', None)
...
if password and confirm_password and password == confirm_password:
    account = Account.objects.create(**validated_data)
    # I assume you extend the User model to this model. you need
    # to use .set_password() so that the password won't be saved as raw
    account.set_password(password)
    account.save()

    return account
Sign up to request clarification or add additional context in comments.

3 Comments

I'm not sure I understand. This is in the Serializer and is using the declared serializer field. So no, it doesn't exist in the model.
Revise your create() function and add the codes in my answer
Made the changes but I'm still getting the 'confirm_password' is an invalid keyword argument for this function error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.