Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to mention password field in serializer?

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?

like image 478
Mahdi Sorkhmiri Avatar asked Mar 09 '18 08:03

Mahdi Sorkhmiri


4 Answers

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)
like image 116
HoangYell Avatar answered Oct 08 '22 12:10

HoangYell


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()
like image 23
Mr.Rusev Avatar answered Oct 08 '22 13:10

Mr.Rusev


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
like image 7
JPG Avatar answered Oct 08 '22 13:10

JPG


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.

like image 3
Shubho Shaha Avatar answered Oct 08 '22 13:10

Shubho Shaha