Raghav Malawat
Posted on June 14, 2020
In the following post we will create a Custom User Model and a Custom User Manager for our Django Project.
Django provides a default User Model but the makers of the same suggest that one should create a custom User Model whenever starting a new project.
Custom User Model in Django gives you immense power to tackle the authentication part of your product, cater it to your own needs anytime.
After tinkering over numerous ways on how to go with it, here's a working solution (most of the use cases tackled).
We have used the following example
We will extend the AbstractBaseUser class DRF provides us with. (though you might have heard about OneToOne Field and AbstractUser, I would suggest go with this approach)
We will use email field as our username
We make email, first name, last name and password mandatory fields (change accordingly to your needs)
We created authentication app which takes care of all our project's authentication functionalities
Steps to follow
- Create a CustomUserManager class
- Create a CustomUser class
- Update your settings.py file
Step 1 : Create a CustomUserManager class
In your authentication/models.py file -
class CustomUserManager(BaseUserManager):
def create_user(self, email, first_name, last_name, password=None):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
if not first_name:
raise ValueError("User must have a first name")
if not last_name:
raise ValueError("User must have a last name")
user = self.model(
email=self.normalize_email(email)
)
user.first_name = first_name
user.last_name = last_name
user.set_password(password) # change password to hash
user.is_admin = False
user.is_staff = False
user.save(using=self._db)
return user
def create_superuser(self, email, first_name, last_name, password=None):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
if not first_name:
raise ValueError("User must have a first name")
if not last_name:
raise ValueError("User must have a last name")
user = self.model(
email=self.normalize_email(email)
)
user.first_name = first_name
user.last_name = last_name
user.set_password(password) # change password to hash
user.is_admin = True
user.is_staff = True
user.save(using=self._db)
return user
def create_staffuser(self, email, first_name, last_name, password=None):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
if not first_name:
raise ValueError("User must have a first name")
if not last_name:
raise ValueError("User must have a last name")
user = self.model(
email=self.normalize_email(email)
)
user.first_name = first_name
user.last_name = last_name
user.set_password(password) # change password to hash
user.is_admin = False
user.is_staff = True
user.save(using=self._db)
return user
Now the next step is to create custom User Model
Step 2 : Create a CustomUser class
In your authentication/models.py file - after CustomUserManager class
class CustomUser(AbstractBaseUser):
ADMIN = 'admin'
STAFF = 'staff'
STATUS = [
(ADMIN, _('Admin User')),
(STAFF, _('Staff User')),
]
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(_('first name'), max_length=30)
last_name = models.CharField(_('last name'), max_length=30)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False) # a admin user; non super-user
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
objects = CustomUserManager()
@staticmethod
def has_perm(perm, obj=None):
# "Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
@staticmethod
def has_module_perms(app_label):
# "Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
def __str__(self):
return "{}".format(self.email)
Step 3 : Update your settings.py file
In your settings..py file add
AUTH_USER_MODEL = 'authentication.CustomUser' # authentication is the app name
- Please don't forget to migrate the models before creating users :)
- Please don't forget to use the CustomUser Model while writing you views :)
Posted on June 14, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.