0
0
DjangoComparisonIntermediate · 4 min read

AbstractUser vs AbstractBaseUser Django: Key Differences and Usage

In Django, AbstractUser is a full user model with all default fields and permissions, ready to extend. AbstractBaseUser provides only core authentication features, requiring you to define all other fields and methods yourself.
⚖️

Quick Comparison

This table summarizes the main differences between AbstractUser and AbstractBaseUser in Django.

FeatureAbstractUserAbstractBaseUser
PurposeComplete user model with username, email, and permissionsMinimal base for custom user models with only authentication features
Fields ProvidedIncludes username, first_name, last_name, email, is_staff, is_active, date_joinedOnly password and last_login
Permissions SupportBuilt-in permissions and groups supportNo permissions; must implement manually
Customization EffortEasy to extend by adding fieldsRequires defining username/email, permissions, and manager
Use CaseWhen default user fields mostly fit your needsWhen you need full control over user model structure
Requires Custom ManagerNo, uses default UserManagerYes, must define custom user manager
⚖️

Key Differences

AbstractUser is a Django model that includes all the standard user fields like username, email, first_name, and last_name. It also includes built-in support for permissions and groups, so you get a fully functional user model out of the box. You can extend it by adding extra fields if needed, making it a quick way to customize users without rewriting core logic.

On the other hand, AbstractBaseUser provides only the essential authentication features: a hashed password and last login timestamp. It does not include username, email, or permissions. This means you must define all user fields, authentication logic, and permissions yourself. You also need to create a custom user manager to handle user creation and querying.

In summary, AbstractUser is for when you want a mostly standard user model with some additions, while AbstractBaseUser is for when you want full control and are ready to implement all user-related features from scratch.

⚖️

Code Comparison

Here is an example of extending AbstractUser by adding a bio field. This shows how simple it is to customize the default user model.

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

class CustomUser(AbstractUser):
    bio = models.TextField(blank=True)

    def __str__(self):
        return self.username
Output
A user model with all default fields plus a bio field; username and authentication work as usual.
↔️

AbstractBaseUser Equivalent

This example shows a minimal custom user model using AbstractBaseUser. It defines an email as the unique identifier and includes a custom user manager to handle user creation.

python
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import PermissionsMixin
from django.db import models

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser 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(email, password, **extra_fields)

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email
Output
A user model with email as username, custom manager, and manual permissions support.
🎯

When to Use Which

Choose AbstractUser when you want a user model close to Django's default with username and permissions already set up, and you only need to add a few extra fields.

Choose AbstractBaseUser when you need full control over the user model, such as using email instead of username for login, or when you want to design a completely custom authentication system.

Using AbstractBaseUser requires more work but offers maximum flexibility, while AbstractUser is faster to implement for common use cases.

Key Takeaways

AbstractUser provides a full user model with standard fields and permissions ready to extend.
AbstractBaseUser offers only core authentication features, requiring full custom implementation.
Use AbstractUser for simple extensions of Django's default user model.
Use AbstractBaseUser for complete control over user fields and authentication logic.
AbstractBaseUser requires a custom user manager; AbstractUser uses Django's default manager.