I am following this tutorial but facing these problems I can\'t fix:
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
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)
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()
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
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
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
.