[Fixed]-Django rest framework user registration?

1👍

Please note that set_password() does NOT save the object and since you have called the super first, your object is already saved with raw password.

Just simply use post_save() to save the password.

def post_save(self, obj, created=False):
    """
    On creation, replace the raw password with a hashed version.
    """
    if created:
        obj.set_password(obj.password)
        obj.save()

13👍

I tried the accepted answer in DRF 3.0.2 and it didn’t work. The password was not being hashed.

Instead, override the create method in your model serializer

    def create(self, validated_data):
        user = User(email=validated_data['email'], username=validated_data['username'])
        user.set_password(validated_data['password'])
        user.save()
        return user

This hashes the password when you create a user using the rest framework, not post_save

6👍

Another approach for DRF 3.X:

from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import make_password

    def create(self, validated_data):    
        if validated_data.get('password'):
            validated_data['password'] = make_password(
                validated_data['password']
            )

        user = get_user_model().objects.create(**validated_data)

        return user

3👍

I’ve used wsgeorge‘s solution to build my own. A blank User object is created just so I can use .set_password():

def create(self, validated_data):
    user = User()
    user.set_password(validated_data['password'])
    validated_data['password'] = user.password
    return super(UserSerializer, self).create(validated_data)

Different from his answer, I do not save the user myself. I leave that to the parent class calling super.

0👍

Override create of model serialzier

def create(self, validated_data):
        if validated_data.get('password'):
            validated_data['password'] = make_password(validated_data['password'])
        return super(UserSerializer, self).create(validated_data)

Be sure to import

from django.contrib.auth.hashers import make_password

-1👍

We can write a signal in User to solve this.

def create_hash(sender, instance=None, *args, **kwargs):
passwd = instance.password
instance.set_password(passwd)


pre_save.connect(create_hash, sender=User)
👤asitm9

Leave a comment