Create Custom User Model in Django

Create Custom User Model in Django

In this post, I will tell you about how to make a custom user model in Django

You must have python installed

Create virtual Env first

Activate virtual environment

install django

Step 1. Start new project

django-admin startproject my_project

Step 2. Create new app

django-admin startapp users

Step 3. Add users app in INSTALLED_APPS in settings.py

image.png

Step 4. Create a new User model in models.py inside the users app

import AbstractBaseUser

from django.contrib.auth.models import AbstractBaseUser

class User(AbstractBaseUser):
    username = models.CharField(max_length=255, unique=True)
    email = models.EmailField(max_length=255, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    updated_at = models.DateTimeField(auto_now = True)
    created_at = models.DateTimeField(auto_now_add = True)

    USERNAME_FIELD = "email"
    REQUIRED_FIELD =  []

USERNAME_FIELD - this value is used for the username field

REQUIRED_FIELD - fields inside is required by default Email and Password is a required field

Create some function for the user class

    def get_username(self):
        return self.email

    def __str__(self):
        return self.email

    @property
    def is_admin(self):
        return self.admin

Step 5. Create Manager for the User model

Inside UserManager class make two function

  • User Function

email = self.normalize_email(email)

normalize_email used for lowercasing the domain portion of the email

def create_user(self, email, password, **extrafields):
        def create_user(self, username, email, password, **extra_fields):
        if not username or username=="":
            raise ValueError(_("User must have an username"))
        if not email or email=="":
            raise ValueError(_("User must have an email"))
        username=username.lower()
        email = email.lower() 
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user
  • Superuser Function
def create_superuser(self, email, password, **extrafields):
        extra_fields.setdefault("is_superuser", True)
        extra_fields.setdefault("is_staff", True)

        if extra_fields.get("is_staff") is not True:
            raise ValueError(_("Staff must have is_staff=true"))
        if extra_fields.get("is_superuser") is not True:
            raise ValueError(_("Superuser must have is_superuser=true"))

        return self.create_user(username, email, password, **extra_fields)

How it will Look Like

image.png

Step 6. Hook our User manager to the user model

class User(AbstractBaseUser):
    ...
    objects = UserManager()

models.py code

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager

# Create your models here.

class UserManager(BaseUserManager):
    def create_user(self, username, email, password, **extra_fields):
        if not username or username=="":
            raise ValueError(_("User must have an username"))
        if not email or email=="":
            raise ValueError(_("User must have an email"))
        username=username.lower()
        email = email.lower() 
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault("is_superuser", True)
        extra_fields.setdefault("is_staff", True)

        if extra_fields.get("is_staff") is not True:
            raise ValueError(_("Staff must have is_staff=true"))
        if extra_fields.get("is_superuser") is not True:
            raise ValueError(_("Superuser must have is_superuser=true"))

        return self.create_user(username, email, password, **extra_fields)

class User(AbstractBaseUser):
    username = models.CharField(max_length=255, unique=True)
    email = models.EmailField(max_length=255, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    updated_at = models.DateTimeField(auto_now = True)
    created_at = models.DateTimeField(auto_now_add = True)
    objects = UserManager()
    USERNAME_FIELD = "email"
    REQUIRED_FIELD =  [] # email and password are required by default

    def get_username(self):
        return self.email

    def __str__(self):
        return self.email

    @property
    def is_admin(self):
        return self.admin

Step 7. Add permissionsmixin

As we know that Django comes with batteries included

there are some permission with which inbuilt user model, group model either we have to remove those or use permissionsmixin to link with them

from django.contrib.auth.models import PermissionsMixin

Inherit PermissionsMixin class in User Model

from django.contrib.auth.models import PermissionsMixin

class User(AbstractBaseUser, PermissionsMixin):
    ....

Steps 8. Update settings.py file

1. Update settings.py

AUTH_USER_MODEL = 'users.User'

2.Run Migrations

python manage.py makemigrations

python manage.py migrate

Now you have successfully created your own User Model

Let's Create User

python createsuperuser

username : give username

email : write email

password : enter password

password(again) : enter password again

Now go to URL

localhost:8000/admin

Login with username and password

If this article needs improvement

Suggest in comments below