I've coded my own AbstractBaseUser and BaseUserManager. Creating users and superusers via terminal works fine. But there is a problem with creating users via form. All user fields are saved properly except password field, which is not hashed (while using set_password()). My models.py:
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class MyUserAccountManager(BaseUserManager):
def create_superuser(self, email, first_name, last_name, password, **other_fields):
other_fields.setdefault('is_staff', True)
other_fields.setdefault('is_superuser', True)
other_fields.setdefault('is_active', True)
if other_fields.get('is_staff') is not True:
raise ValueError(
'Superuser must be assigned to is_staff=True.')
if other_fields.get('is_superuser') is not True:
raise ValueError(
'Superuser must be assigned to is_superuser=True.')
return self.create_user(email, first_name, last_name, password, **other_fields)
def create_user(self, email, first_name, last_name, password, **other_fields):
if not email or not first_name or not last_name or not password:
raise ValueError('You must provide more data')
email = self.normalize_email(email)
user = self.model(email=email, first_name=first_name, last_name=last_name, **other_fields)
user.set_password(password)
user.save()
return user
class MyUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField('Email address', unique=True, max_length=30)
first_name = models.CharField('First name', max_length=30)
last_name = models.CharField('Last name', max_length=30)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
objects = MyUserAccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
def __str__(self):
return self.email
And my forms.py:
from django import forms
from .models import MyUser
class MyUserForm(forms.ModelForm):
email = forms.CharField(widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
first_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First name', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last name', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
class Meta:
model = MyUser
fields = ['email',
'first_name',
'last_name',
'password']
I think there is no need to show views.py and html file (full standard).
Any help is appreciated!