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
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
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)
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'
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
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)
Nice informational article.
Coincidentally I was reading on the same and came across this nice article. It can be a good extra resource.