how to mention password field in serializer?
13,086
Solution 1
to hash password, call:
make_password(origin_password)
example serializers.py:
from rest_framework import serializers
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
class UserSerializer(serializers.HyperlinkedModelSerializer):
password = serializers.CharField(
write_only=True,
required=True,
help_text='Leave empty if no change needed',
style={'input_type': 'password', 'placeholder': 'Password'}
)
class Meta:
model = User
fields = ('url', 'username', 'email', 'password')
def create(self, validated_data):
validated_data['password'] = make_password(validated_data.get('password'))
return super(UserSerializer, self).create(validated_data)
Solution 2
Change serializers.py
as below
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ('username', 'email', 'password', 'firstname', 'last name')
def create(self, validated_data):
user = super().create(validated_data)
user.set_password(validated_data['password'])
user.save()
return user
def update(self, instance, validated_data):
user = super().update(instance, validated_data)
try:
user.set_password(validated_data['password'])
user.save()
except KeyError:
pass
return user
Solution 3
There was no special field for password in DRF. In my current project we used to define password field as CharField
with write_only=True
inside serializer class.
Solution 4
The @MahdiSorkhmiri answer is working perfectly for me. Here is how my file is looking write now.
class UserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(
validators=[UniqueValidator(UserModel.objects.all())]
)
password = serializers.CharField(
min_length=4,
write_only=True,
required=True,
style={'input_type': 'password'}
)
def create(self, validated_data):
fields = ['username', 'password', 'email']
data = {f: validated_data.get(f) for f in fields}
return UserModel.objects.create_user(**data)
class Meta:
model = UserModel
fields = 'username email last_name first_name password'.split()
Author by
Mahdi Sorkhmiri
Back-end developer with years of experience in developing high-quality code on top of different technology stacks and with different architectures. interested in hardware and IoT.
Updated on July 21, 2022Comments
-
Mahdi Sorkhmiri almost 2 years
I have a custom user for authentication and want to create a serializer class for it my custom user's model is like this :
class User (AbstractUser): bio = models.TextField(max_length=500, blank=True) birth_date = models.DateField(null=True, blank=True) image=models.FileField(null=True , blank=True)
and my serializer is :
class UserSerializer (serializers.ModelSerializer): class Meta: model = User fields = ('username' ,'email' ,'password' ,'firstname' , 'last name' )
how could I mention that the password field is a password and its content must be hashed?
-
Mahdi Sorkhmiri about 6 yearsthis code you added hides the password field in getting request but it's still not hashed and look like a normal text
-
JPG about 6 yearsDid your password not hashed? Can you add your current response as screenshot or something ?
-
Shubho Shaha about 6 yearsSomething like this
password = serializers.CharField(max_length=128, write_only=True, required=True)
-
Aman Sharma almost 6 years@MahdiSorkhmiri, I don't know how to hash it but to hide the text you can wirte it like this: password = serializers.CharField(write_only=True, style={'input_type': 'password'})
-
help-info.de about 5 yearsWelcome to Stack Overflow! Here is a guide on How to Answer. Please don't add "thanks" as answers. They don't actually provide an answer to the question, and can be perceived as noise by its future visitors. Once you earn enough reputation, you will gain privileges to upvote answers you like. This way future visitors of the question will see a higher vote count on that answer, and the answerer will also be rewarded with reputation points. See Why is voting important.
-
Oli over 4 yearsThis will write the raw password directly into the database, rather than hashing it via user.set_password (which itself uses make_password). Making it write_only is only half the job.
-
JPG over 4 years@Oli Yeah..you were right. Thanks for the correction and I have updated the answer :)
-
Evren Bingøl over 3 yearsyou need to call make_password to hash
-
Enzo Dtz almost 3 yearswith this it keep showing on OPT request, but not on GET ones. perfect! thanks
-
Elias Prado almost 3 yearsJust to remmember that set_password() is only for User model. For those who are looking to hash not User password you should use make_password method from auth.hashers.
-
Elias Prado almost 3 yearsThe greater of this approach is that the make_password method can also be used for not User serialzer method too. Thank you for your answer.