The difference on AbstractUser and AbstractBaseUser
Tags: django, beginners, codenewbie, hacktoberfest
Published: 2022-10-05 09:34:17

### 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:

```python
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.

```python
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.
<br>
 


- **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.

```python
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

```python
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
```
<br>

## 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_.

<br>
For feedback, reach out on [Twitter](https://twitter.com/ItsWeshy)