Rohit B
Rohit B

Reputation: 61

Django REST Framework user registration Validation confusion

I am trying to register a user with Django REST API with two different methods

With method 1 everything works fine but it gives

This problem :

https://stackoverflow.com/questions/43952178/django-rest-framework-user-registration-confusion

And with method 2 it gives the following error but is creating users in backend

AttributeError at /api/users/register/

Got AttributeError when attempting to get a value for field password2 on serializer UserCreateSerializer. The serializer field might be named incorrectly and not match any attribute or key on the User instance. Original exception text was: 'User' object has no attribute 'password2'.

Code:

from django.contrib.auth import get_user_model
from rest_framework.exceptions import ValidationError

from rest_framework.serializers import (ModelSerializer,CharField)

User = get_user_model()


class UserCreateSerializer(ModelSerializer):
    password2 = CharField(label='Confirm Password')
    class Meta:
        model = User
        fields = [
            'username',
            'password',
            'password2',
            'email',
        ]
        extra_kwargs = {
            'password' : {'write_only': True},
            'password2': {'write_only': True},
        }

    def validate_password(self, value):
        data = self.get_initial()
        password = data.get('password2')
        password2 = value
        if password != password2:
            raise ValidationError('Passwords must match')
        return value

    def validate_password2(self, value):
        data = self.get_initial()
        password = data.get('password')
        password2 = value
        if password != password2:
            raise ValidationError('Passwords must match')
        return value

method 1:

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

method 2:

 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

Note: Using Python3 , Django 10.7 & Django REST framework 3

Upvotes: 1

Views: 5158

Answers (2)

Jim.Z
Jim.Z

Reputation: 41

please try this: add write_only=True in the password2

class UserCreateSerializer(ModelSerializer):
    password2 = CharField(label='Confirm Password', write_only=True)
    ...

Upvotes: 0

zaidfazil
zaidfazil

Reputation: 9235

The problem in your method is that you are passing the password2, which is not an attribute of the User model.

From reading your code, I think you could try something like this,

Instead of repeatedly validating each password field you could do an object wide validation for that.

def validate(self, data):
    password = data.get('password')
    confirm_password = data.pop('password2')
    if password != confirm_password:
        raise ValidationError('.............')
    return data

The create method you have written would suffice, I hope.. Try this and let me know if anything comes up..

EDIT

Edit your create method,

def create (self, validated_data):
    email = validated_data.get('email')
    username = validated_data.get('username')
    password = validated_data.get('password')
    try:
        user = User.objects.create(username=username, email=email)
        user.set_password(password)
        user.save()
        return user
    except Exception as e:
        return e

The KeyError maybe triggered, if any of the email, password, username are not available.

Upvotes: 2

Related Questions