django custom user can't set attribute error - django

I followed CodingEntrepreneurs tutorial on Custom Users and extended it to have 3 types of users: school, parent and vendor.
I have created view, form for each type of user.
In forms.py I have
class ParentSignUpForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta():
model = User
fields = ('email', )
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
user = super(ParentSignUpForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.is_parent = True
user.save()
return user
I try to change is_parent attribute from False to True. However, error is:
File "/home/azamat/dev/dj_test/src/accounts/forms.py", line 137, in save
user.is_parent = True
AttributeError: can't set attribute
How to solve this issue? Or any better way to save users with different types?
UPDATE:
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager
)
class UserManager(BaseUserManager):
def create_user(self, email, password=None, is_staff=False, is_admin=False, is_active=True, is_parent=False, is_school=False, is_vendor=False):
if not email:
raise ValueError("Users must have an email address")
if not password:
raise ValueError("Users must have a password")
user_obj = self.model(
email = self.normalize_email(email)
)
user_obj.set_password(password) # change user password
user_obj.parent = is_parent
user_obj.school = is_school
user_obj.vendor = is_vendor
user_obj.active = is_active
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.save(using=self._db)
return user_obj
def create_parentuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_parent=True
)
return user
def create_schooluser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_school=True
)
return user
def create_vendoruser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_vendor=True
)
return user
def create_staffuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_staff=True
)
return user
def create_superuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_staff=True,
is_admin=True,
)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
active = models.BooleanField(default=True) # can login
parent = models.BooleanField(default=False) # parent user
school = models.BooleanField(default=False) # school admin user
vendor = models.BooleanField(default=False) # vendor user
staff = models.BooleanField(default=False) # staff user non superuser
admin = models.BooleanField(default=False) # superuser
timestamp = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email' #username
objects = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_parent(self):
return self.parent
#property
def is_school(self):
return self.school
#property
def is_vendor(self):
return self.is_vendor
#property
def is_active(self):
return self.active
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin

How I solved it:
I have added REQUIRED_FIELDS = ['parent', 'school', 'vendor' ] to my model.py So now on my registration page, I have 3 check buttons where I can select a needed type of user.
In forms.py I left only RegisterForm and deleted register forms for my 3 user types
class RegisterForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email', **'parent', 'school', 'vendor'**) #'added 3 fields',)
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(RegisterForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
# user.active = False # send confirmation email
if commit:
user.save()
return user

Related

'User' object has no attribute 'is_staff'

I am working with user authentication system where I created a user registration model using AbstractBaseUser. then I create super User using terminal . But when I go the admin and write email and password there . It gives me the error that: 'User' object has no attribute 'is_staff'
My models.py file is:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser,BaseUserManager
SUBJECT_CHOICES = (
('math','Math'),
('physics','Physics'),
('chemistry','Chemistry'),
)
class UserManager(BaseUserManager):
def create_user(self, email, full_name=None, password=None, is_staff=False, is_admin=False):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
user_obj = self.model(email=self.normalize_email(email), full_name=full_name)
user_obj.set_password(password)
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.save(using=self._db)
return user_obj
def create_staffuser(self,email,full_name=None,password=None):
user = self.create_user(email, full_name=full_name,password=password)
return user
def create_superuser(self,email, full_name=None,password=None):
user = self.create_user(email, full_name=full_name, password=password)
return user
class User(AbstractBaseUser):
full_name = models.CharField(max_length=255, blank=True, null=True)
sur_name = models.CharField(max_length=255, blank=True, null=True)
email = models.EmailField(max_length=255 ,unique=True)
choose_subject = models.CharField(choices=SUBJECT_CHOICES , max_length=100)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
time_stamp = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
object = UserManager()
def __str__(self):
return self.full_name
my forms.py file is:
class RegisterForm(forms.ModelForm): # A form for creation new user included all all the required fields including repeated password
password1 = forms.CharField(label='Enter Password' , widget=forms.PasswordInput )
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields=('full_name','sur_name','email','choose_subject')
def clean_password2(self): # check that two password entries match or not
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("password dont match")
return password2
def save(self , commit=True): #save the provided password in hashed format
user = super(RegisterForm , self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
#user.active = False #send confirmation email
if commit:
user.save()
return user
my views.py is:
class RegisterView(CreateView):
form_class = RegisterForm
template_name = "users/register.html"
success_url = '/register'
Thank You.
There are two ways to resolve this problem
Number one: create property method into your user model:
#property
def is_staff(self):
return self.staff
Number two: rename "staff" field to "is_staff", it would be righter
It should be
is_staff
but not staff...
You can have it working if you type staff or change the model field to
is_staff.

how can i add phone number field from class profile to class user?

I need to add phone number into my required model's field, so I'm doing this but is not working correctly
so if everyone knows how can I add a Phone number, please help me:
#models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from phonenumber_field.modelfields import PhoneNumberField
class UserManager(BaseUserManager):
def create_user(self, phone_number, email, password=None, is_active=True, is_staff=False, is_admin=False):
if not email:
raise ValueError("User Must have an Email Address")
if not password:
raise ValueError("User Must have a Password")
if not phone_number:
raise ValueError("User Must have a Phone Number")
user_obj = self.model(email=self.normalize_email(email))
user_obj.set_password(password) # change user password
user_obj.phone_number(phonenumber_field)
user_obj.staff = is_staff
user_obj.active = is_active
user_obj.admin = is_admin
user_obj.save(using=self._db)
return user_obj
# staff user
def create_staffuser(self, email, password=None):
user = self.create_user(
email,
password=password,
phone_number=PhoneNumberField,
is_staff=True
)
return user
# admin user
def create_superuser(self, email, password=None):
user = self.create_user(
email,
password=password,
phone_number=PhoneNumberField,
is_staff=True,
is_admin=True
)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
# full_name = models.CharField(max_length=255, blank=True, null=True)
active = models.BooleanField(default=True) # can log in
staff = models.BooleanField(default=False) # staff user non super user
admin = models.BooleanField(default=False) # super user
timestamp = models.DateTimeField(auto_now_add=True)
phone_number = PhoneNumberField()
USERNAME_FIELD = 'email' # username
REQUIRED_FIELDS = [] # FULL_NAME
object = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
I wanna add phone number in class profile and include this to the required field on user class, but I cant
every time i have error : raise TypeError("Can't convert %s to PhoneNumber." % type(value).name)
TypeError: Can't convert int to PhoneNumber.
You can't add a ModelField class to an attribute. Instead try to pass the value through method arguments. As per documentation, you should be able to pass the value if the field is required.
So, update your manager method like this:
class UserManager(BaseUserManager):
def create_user(self, email, phone_number, password=None, is_active=True, is_staff=False, is_admin=False):
if not email:
raise ValueError("User Must have an Email Address")
if not password:
raise ValueError("User Must have a Password")
if not phone_number:
raise ValueError("User Must have a Phone Number")
user_obj = self.model(email=self.normalize_email(email))
user_obj.set_password(password) # change user password
user_obj.phone_number = phone_number
user_obj.staff = is_staff
user_obj.active = is_active
user_obj.admin = is_admin
user_obj.save(using=self._db)
return user_obj
# staff user
def create_staffuser(self, email, phone_number, password=None):
user = self.create_user(
email,
password=password,
phone_number=phone_number,
is_staff=True
)
return user
# admin user
def create_superuser(self, email, phone_number, password=None):
user = self.create_user(
email,
password=password,
phone_number=phone_number,
is_staff=True,
is_admin=True
)
return user
And add phone_number to required fields in model:
REQUIRED_FIELDS = ['phone_number']

RegisterForm() missing 1 required positional argument: 'request'

So I'm making a custom user model. This is what I'am following Here. I have been pretty much following the tutorial but still I cant make it done.
Error: RegisterForm() missing 1 required positional argument: 'request'.
here's my code.
forms.py
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from .models import User
class UserAdminCreationForm(forms.ModelForm):
"""
A form for creating new users. Includes all the required
fields, plus a repeated password.
"""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email',)
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('email', 'password', 'active', 'admin')
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class LoginForm(forms.ModelForm):
email = forms.EmailField(label='Email')
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email', 'password',)
widgets = {
'email' : forms.EmailInput(
attrs={'class':'form-control', 'place_holder': '', }),
'password' : forms.PasswordInput(
attrs={'class':'form-control' }),
}
class RegisterForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email',)
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("email is taken")
return email
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
models.py
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class UserManager(BaseUserManager):
def create_user(self, email, full_name, password=None, is_staff=False, is_active=True, is_admin=False):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('Users must have an email address')
if not full_name:
raise ValueError('Users must have an full name')
if not password:
raise ValueError('Users must have a password')
user = self.model(
email=self.normalize_email(email),
)
user.full_name = full_name
user.set_password(password)
user.staff = is_staff
user.admin = is_admin
user.active = is_active
user.save(using=self._db)
return user
def create_staffuser(self, email, password):
"""
Creates and saves a staff user with the given email and password.
"""
user = self.create_user(
email,
password=password,
)
user.staff = True
user.save(using=self._db)
return user
def create_superuser(self, email, full_name, password):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.model(
email=self.normalize_email(email)
)
user.full_name = full_name
user.set_password(password)
user.full_name = full_name
user.staff = True
user.admin = True
user.save(using=self._db)
return user
# Create your models here.
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
full_name = models.CharField(max_length=255, null=True, blank=True)
active = models.BooleanField(default=True) # to login
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
created_date = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name'] # Email & Password are required by default.
objects = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
return self.staff
#property
def is_admin(self):
"Is the user a admin member?"
return self.admin
#property
def is_active(self):
"Is the user active?"
return self.active
class Account_type(models.Model):
name = models.CharField(max_length=50, null=True, blank=True)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
account_type = models.ForeignKey(Account_type, on_delete=models.CASCADE)
register.html
from django.shortcuts import render, redirect
from . forms import RegisterForm, LoginForm
# Create your views here.
def RegisterForm(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
else:
form = RegisterForm()
context = {
'form' : form
}
return render(request, 'account/register.html', context)
The view logic is simple as you can see. Just saving up the request into the database. The tutorial itself did not tell anything about the view for login and register.
So, What am I doing wrong here.
Thank you
The problem is that your view RegisterForm has the same name as your form, hence if you call RegisterForm in your view, it will resolve to the view function, and make a recursive call.
Normally (top-level) functions are written in snake_case, hence you can rewrite it to register_form, or even better register (since it is not a form at all):
from django.shortcuts import render, redirect
from . forms import RegisterForm, LoginForm
# Create your views here.
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
return redirect('some-view-name')
else:
form = RegisterForm()
context = {
'form' : form
}
return render(request, 'account/register.html', context)
Normally a successful POST request results in a redirect to implement the Post/Redirect/Get pattern [wiki]. So I strongly advise you to use redirect(..) [Django-doc] and replace some-view-name with the name of a view to which you want to redirect.

Django form creates default User rather than acustom User. How do I create a Custom User?

Trying to extend Django's basic user model to a custom user model. I have a form for users to register, but when the form is sent it creates a default user, not a custom user.
I want it to create a custom user. The only way I seem to be able to create a custom user currently is through admin.
Here is my Django custom user model, which exists and can add users via admin.
class MyUserManager(BaseUserManager):
def create_user(first_name, last_name, zipcode, email, username, password):
if not first_name:
raise ValueError("Users must have a first name.")
if not last_name:
raise ValueError("Users must have a last name.")
if not zipcode:
raise ValueError("Users must have a zipcode.")
if not email:
raise ValueError("Users must have an email.")
if not username:
raise ValueError("Users must have a username.")
if not password:
raise ValueError("Users mush have a password.")
user=self.model(
first_name = first_name,
last_name = last_name,
zipcode = zipcode,
email=email,
is_logged_in=is_logged_in,
is_bot=is_bot
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=25,
validators = [
RegexValidator(regex = USERNAME_REGEX,
message='Firstname must be alphanumeric or contain numbers',
code='invalid_firstname'
)]
)
last_name = models.CharField(max_length=25,
validators = [
RegexValidator(regex = USERNAME_REGEX,
message='Lastname must be alphanumeric or contain numbers',
code='invalid_lastname'
)]
)
zipcode = models.CharField(
max_length=10,
null=True,
blank=True,
help_text="zipcode",
validators=[RegexValidator(
regex=r'^(^[0-9]{5}(?:-[0-9]{4})?$|^$)',
message=(u'Must be valid zipcode in formats 12345 or 12345-1234'),
)],
)
email = models.EmailField(max_length = 250,
unique=True,
verbose_name = 'email_address')
username = models.CharField(max_length = 25,
validators = [
RegexValidator(regex = USERNAME_REGEX,
message='Username must be alphanumeric or contain numbers',
code='invalid_username'
)],
unique=True
)
password = models.CharField(max_length =25,
null=True)
objects=MyUserManager()
def get_short_name(self):
# The user is identified by their email address
return self.email
def has_perm(self, perm, obj=None):
#"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
#"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
def __str__(self):
return f'{self.first_name} ({self.last_name}) ({self.email})'
Here is my views file where I'm saving the form.
#views.py
def registration(request):
if request.method == "POST":
form = CustomUserCreationForm(request.POST, instance=request.user)
if form.is_valid():
profile = form.save(commit=False)
profile.user = request.user
profile.save()
messages.success(request, f'Your account has been created! Please proceed to agreements and payment.')
return redirect('agreements_page')
else:
form = CustomUserCreationForm()
return render(request, 'registration.html', {'form': form})
here is my form.py file
class CustomUserCreationForm(forms.ModelForm):
username = forms.CharField(label='Username', widget=forms.TextInput(attrs={'class': "form-control"}))
password1 = forms.CharField(label='Password', widget=forms.PasswordInput(attrs={'class': "form-control"}))
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput(attrs={'class': "form-control"}))
first_name = forms.CharField(label='First Name', widget=forms.TextInput(attrs={'class': "form-control"}))
last_name = forms.CharField(label='Last Name', widget=forms.TextInput(attrs={'class': "form-control"}))
zipcode = forms.CharField(label='Zipcode', widget=forms.NumberInput(attrs={'class': "form-control"}))
email = forms.CharField(label= 'Email', widget=forms.EmailInput(attrs={'class': "form-control"}))
class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'email', 'zipcode', 'username']
def clean_password(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords do not match")
return password2
def save(self, commit=True):
user = super(CustomUserCreationForm, self).save(commit=False)
user.username = self.cleaned_data['username']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.zipcode = self.cleaned_data['zipcode']
user.email = self.cleaned_data['email']
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
You need to tell your app that your default user model is CustomUser. To do that, you need to add this to your settings.py:
AUTH_USER_MODEL = 'your_app_name.CustomUser'
And in your view, you need to access your user such as:
profile.user = request.user.get_profile()
This is also specified in a complete custom user example in the official site:
Finally, specify the custom model as the default user model for your project using the AUTH_USER_MODEL setting in your settings.py.

Django custom user authentication is not working properly

i am using custom user authentication model which uses an email address as the username and creates the user but even if password1 is different than password2 the registration completes successfully. i am unable to debug the problem.
here is models.py file:
class UserManager(auth_models.BaseUserManager):
def create_user(self, email, first_name, last_name, password):
"""
Creates and saves a user with given email,
first name, last name and password.
"""
if not email:
raise ValueError("users must have an email address")
user = self.model(
email=UserManager.normalize_email(email),
first_name=first_name,
last_name=last_name,
)
user.set_password(password)
user.save(self._db)
return user
def create_superuser(self, email, first_name, last_name, password):
"""
Creates and saves a super_user with given email,
first name, last name and password.
"""
if not email:
raise ValueError("users must have an email address")
user = self.model(
email=UserManager.normalize_email(email),
first_name=first_name,
last_name=last_name,
)
user.is_admin = True
user.set_password(password)
user.save(self._db)
return user
class User(auth_models.AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
joined_at = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', ]
def get_full_name(self):
return self.first_name + " " + self.last_name
def get_short_name(self):
return self.first_name
def __str__(self):
return self.get_full_name() + ", email= " + self.email
#property
def is_staff(self):
return self.is_admin
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
class Meta:
verbose_name_plural = "users"
admin.py
class UserCreationForm(forms.ModelForm):
"""
A form for creating new users. Includes all the required
fields, plus a repeated password.
"""
password1 = forms.CharField(label='password', widget=forms.PasswordInput)
password2 = forms.CharField(label='confirm password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
def clean_password(self):
"""
check that the two password entries match
"""
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("passwords don't match")
return password2
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
"""
A form for updating users. includes all the fields
on the user, but replaces the password field with
the admin's password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('first_name', 'last_name', 'email', 'password', 'is_active', 'is_admin')
def clean_password(self):
"""
Regardless of what the user provides, return the initial value.
This is done here, rather than on the field, because the field
does not have access to the initial value.
"""
return self.initial["password"]
views.py
def register(request):
args = {}
args.update(csrf(request))
if request.method == 'POST':
form = UserCreationForm(request.POST)
args['form'] = form
if form.is_valid():
form.save()
return HttpResponseRedirect('/home/')
else:
args['form'] = UserCreationForm()
return render_to_response('authentication/signup.html', args, context_instance=RequestContext(request))
Try moving the password comparison logic present in the clean_password() function to a clean() function in the UserCreationForm.
The clean_fieldname() function should operate on the field fieldname and not any other field.
Also, when fields validation depends on each other then the best place to place the validation logic is inside the clean() method.
From Django docs:
We are performing validation on more than one field at a time, so the
form’s clean() method is a good spot to do this.
By the time the form’s clean() method is called, all the individual
field clean methods will have been run (the previous two sections), so
self.cleaned_data will be populated with any data that has survived so
far. So you also need to remember to allow for the fact that the
fields you are wanting to validate might not have survived the initial
individual field checks.
Code:
class UserCreationForm(forms.ModelForm):
...
def clean(self):
cleaned_data = super(UserCreationForm, self).clean()
password1 = cleaned_data.get("password1")
password2 = cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("passwords don't match")
return cleaned_data
The problem is, you doesn't has a 'password' field,
you need change the method name to, clean_password1 or clean_password2.
the method you created clean_password, will never be called
because there is no field called password
def clean_password1(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("passwords don't match"")
return password1