Custom User Model and Manager ( Django REST Framework )

raghavmalawat

Raghav Malawat

Posted on June 14, 2020

Custom User Model and Manager ( Django REST Framework )

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

  1. Create a CustomUserManager class
  2. Create a CustomUser class
  3. 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

  1. Please don't forget to migrate the models before creating users :)
  2. Please don't forget to use the CustomUser Model while writing you views :)
💖 💪 🙅 🚩
raghavmalawat
Raghav Malawat

Posted on June 14, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related