DEV Community

Cover image for The difference on AbstractUser and AbstractBaseUser
It's pronounced W3SHY
It's pronounced W3SHY

Posted on • Edited on

The difference on AbstractUser and AbstractBaseUser

Introduction

It is important to understand the difference between AbstractUser and AbstractBaseUser when you are a Django developer. I am hoping that this article will help you answer the confusions the two come with.

First, we explain…

AbstractUser

AbstractUser class initially has 11 fields, the same as default "User" class as shown below and for the subclass of AbstractUser class, you can add new fields, change and remove initial fields.

Keep it in mind that "username" and "email" fields in the initial fields of AbstractUser class are special and only "username" fields have Unique Constraint.
These are the initial fields of AbstractUser class which default "User" class has as shown below:

id 
password 
last_login 
is_superuser 
username (Special, Unique Constraint) 
first_name 
last_name 
email (Special) 
is_staff 
is_active 
date_joined
Enter fullscreen mode Exit fullscreen mode

AbstractBaseUser

AbstractBaseUser class initially has 3 fields as shown below and for the subclass of AbstractBaseUser class, you can add new fields, change and remove initial fields the same as AbstractUser class.

These are the initial fields of AbstractBaseUser class as shown below:

id 
password 
last_login
Enter fullscreen mode Exit fullscreen mode

From what we have seen...

  • AbstractUser is a full User model, complete with fields which you’re probably already used to. It's an abstract class so that you can inherit from it and add your own profile fields required for your database and methods. It’s a change of schema of the database. The fields you might add are like date_of_birth, location to the User model which means you will get the complete field which was there by default plus your added fields.
from django.db import models
from django.contrib.auth.models import AbstractUser

# TODO: First you import the AbstractUser from django auth model 
#  and inherit it with the Custom User model

# Create your models here
class CustomUser(AbstractUser):
    date_of_birth = models.DateTimeField()
    location = models.CharField(max_length=100)
    nickname = models.CharField(max_length=100)
Enter fullscreen mode Exit fullscreen mode

The above example you will get all the fields of the User model, additionally the fields that we defined here: date_of_birth, location & nickname.

  • AbstractBaseUser only contains the authentication functionality: you have to supply them when you subclass. It makes fewer assumptions.
    • You have to tell it what field will represent the username, the fields that are required, and how those users will be managed.
from django.db import models
from django.contrib.auth.models import AbstractBaseUser

# TODO: First you import the AbstractBaseUser from django auth model 
#  and inherit it with the Custom User model

# Create your models here
class CustomUser(AbstractBaseUser):
    email = models.EmailField(max_length=256, unique=True, verbose_name='email')
    date_of_birth = models.DateTimeField()
    location = models.CharField(max_length=100)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = 'location'

Enter fullscreen mode Exit fullscreen mode

Keep it in mind that as you've already noticed, AbstractBaseUser class also has "USERNAME_FIELD" and by default, no field is set to "USERNAME_FIELD" so you need to set one existing field to it as shown above otherwise there is an error. In addition, no fields are set to "REQUIRED_FIELDS"

It is important to note that you can also set email as your unique identifier by using AbstractUser, this can be done by setting username = None and USERNAME_FIELD = 'email' as shown below

from django.db import models
from django.contrib.auth.models import AbstractUser

# TODO: First you import the AbstractUser from django auth model 
#  and inherit it with the Custom User model

# Create your models here
class CustomUser(AbstractUser):
    username = None
    email = models.EmailField(max_length=256, unique=True, verbose_name='email')

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = 'location'

    def __str__(self):
        return self.email
Enter fullscreen mode Exit fullscreen mode

In Conclusion, which one should you use?

Main difference basically lies on Use-case. Say for example you no longer need the existing User class provided by Django and you only care about authentication functionalities provided by the User class and your own custom fields. In that case, you should use AbstractBaseUser. In another case, you want to use existing User Fields and functionalities but on top of that you would like to add some extra fields and methods. In that case, you should use AbstractUser.



For feedback, reach out on Twitter

Top comments (1)

Collapse
 
steekam profile image
Kamau Wanyee

Nice informational article.
Coincidentally I was reading on the same and came across this nice article. It can be a good extra resource.