Bird
Raised Fist0
Djangoframework~15 mins

Custom user model with AbstractUser in Django - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Custom user model with AbstractUser
What is it?
A custom user model with AbstractUser in Django is a way to create your own user class by extending Django's built-in AbstractUser class. This lets you add extra fields or change behavior while keeping all the default user features. It is useful when the default user model does not fit your application's needs. This approach keeps compatibility with Django's authentication system.
Why it matters
Without customizing the user model early, you might face big problems later if you need extra user information or different login methods. Changing the user model after starting a project is very hard and error-prone. Custom user models let you design your user data exactly how your app needs it, making your app more flexible and future-proof.
Where it fits
Before learning this, you should understand Django basics, models, and the default User model. After this, you can learn about custom user managers, authentication backends, and user permissions to build full user systems.
Mental Model
Core Idea
Extending AbstractUser lets you build a user model tailored to your app by adding fields and methods while keeping Django's built-in user features intact.
Think of it like...
It's like customizing a car by starting with a standard model and adding your own features, instead of building a car from scratch or using a plain one that doesn't fit your needs.
┌─────────────────────────────┐
│       AbstractUser          │
│  (built-in Django user)     │
│  - username                │
│  - password                │
│  - email                   │
│  - first_name              │
│  - last_name               │
└─────────────┬───────────────┘
              │ extends
              ▼
┌─────────────────────────────┐
│     CustomUserModel          │
│  - all AbstractUser fields   │
│  - extra fields (e.g., phone)│
│  - custom methods           │
└─────────────────────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Django's Default User
🤔
Concept: Learn what the default User model provides and why it might be limited.
Django comes with a built-in User model that has basic fields like username, password, email, first and last name. It supports authentication and permissions out of the box. However, it does not include fields like phone number or profile picture. If your app needs more user info, the default model is not enough.
Result
You know the default User model's fields and limitations.
Understanding the default User model helps you see why customizing it is often necessary for real apps.
2
FoundationWhat is AbstractUser in Django?
🤔
Concept: AbstractUser is a base class you can extend to create your own user model with default fields included.
AbstractUser is a Django class that has all the fields and methods of the default User model but is designed to be extended. Unlike the default User, AbstractUser is abstract, meaning it doesn't create a database table by itself. You create your own user model by inheriting from AbstractUser and adding fields or methods.
Result
You understand AbstractUser as a customizable base user class.
Knowing AbstractUser lets you customize users without losing built-in features.
3
IntermediateCreating a Custom User Model by Extending AbstractUser
🤔Before reading on: Do you think you can add new fields directly to AbstractUser or must you create a new class? Commit to your answer.
Concept: You create a new user model class that inherits from AbstractUser and add your extra fields there.
To customize, define a new class in your app's models.py that inherits from AbstractUser. Add any new fields you want, like phone_number or birth_date. For example: from django.contrib.auth.models import AbstractUser from django.db import models class CustomUser(AbstractUser): phone_number = models.CharField(max_length=15, blank=True) Then update your settings.py to use this model: AUTH_USER_MODEL = 'yourapp.CustomUser'
Result
You have a new user model with default and custom fields.
Creating a subclass of AbstractUser is the cleanest way to extend user data while keeping Django's auth features.
4
IntermediateUpdating Settings and Migrations for Custom User
🤔Before reading on: Should AUTH_USER_MODEL be set before or after running initial migrations? Commit to your answer.
Concept: You must tell Django to use your custom user model before creating database tables.
In settings.py, set AUTH_USER_MODEL to your custom user model before running migrations. This ensures Django creates the correct tables. If you change AUTH_USER_MODEL after migrations, you get errors. Then run: python manage.py makemigrations python manage.py migrate This creates the database schema for your custom user.
Result
Django uses your custom user model in the database and authentication.
Setting AUTH_USER_MODEL early avoids complex migration problems later.
5
IntermediateUsing Custom User Model in Admin and Forms
🤔Before reading on: Do you think the default UserAdmin works automatically with your custom user? Commit to your answer.
Concept: You need to customize Django admin and forms to work with your new user model fields.
Django's admin uses UserAdmin for the default User. For your custom user, you must create a new admin class inheriting from UserAdmin and register it. You also update fieldsets to include new fields. Example: from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser class CustomUserAdmin(UserAdmin): fieldsets = UserAdmin.fieldsets + ( ("Extra Info", {"fields": ("phone_number",)}), ) admin.site.register(CustomUser, CustomUserAdmin) Similarly, update forms if you use custom user creation or change forms.
Result
Your custom user fields appear and can be edited in Django admin.
Admin customization is necessary to manage new user fields easily.
6
AdvancedHandling Authentication and User Creation
🤔Before reading on: Will Django's default user creation forms work with your custom user model? Commit to your answer.
Concept: You often need custom user creation and change forms to handle new fields and validation.
Django's default UserCreationForm and UserChangeForm expect the default User model. For a custom user, create new forms inheriting from these and update Meta to use your model. Add fields and validation as needed. Use these forms in admin or your views to create and update users properly.
Result
User creation and update handle your custom fields correctly.
Custom forms ensure your new user fields are properly handled during signup and editing.
7
ExpertCommon Pitfalls and Best Practices in Custom User Models
🤔Before reading on: Can you change AUTH_USER_MODEL after initial migrations without issues? Commit to your answer.
Concept: Changing user model mid-project causes complex errors; plan your user model early and follow best practices.
Once you run migrations with a user model, changing AUTH_USER_MODEL is very difficult and can break your database and auth system. Always define your custom user model before the first migration. Use AbstractUser to keep compatibility. Avoid adding too many unrelated fields; consider profile models if needed. Test authentication flows thoroughly.
Result
You avoid migration errors and maintain a stable user system.
Knowing these pitfalls saves time and prevents hard-to-debug errors in production.
Under the Hood
AbstractUser is an abstract Django model that defines fields and methods for user authentication, permissions, and profile data. When you extend it, Django creates a concrete database table for your custom user model including inherited and new fields. Django's authentication system uses the AUTH_USER_MODEL setting to know which model to use for login, permissions, and sessions. Forms and admin classes rely on this model to provide user management features.
Why designed this way?
Django provides AbstractUser to allow developers to customize user data without rewriting authentication logic. It separates the user data structure from authentication mechanisms. This design avoids duplicating code and supports flexibility. Alternatives like AbstractBaseUser require more work but offer full control. AbstractUser balances ease and customization.
┌─────────────────────────────┐
│       AbstractUser          │
│  (abstract base model)      │
│  - username                │
│  - password                │
│  - email                   │
│  - permissions             │
└─────────────┬───────────────┘
              │ inherited by
              ▼
┌─────────────────────────────┐
│     CustomUserModel          │
│  - all AbstractUser fields   │
│  - extra fields             │
└─────────────┬───────────────┘
              │ used by
              ▼
┌─────────────────────────────┐
│  Django Authentication      │
│  - login/logout             │
│  - permissions checks      │
│  - sessions                 │
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Can you safely change AUTH_USER_MODEL after running migrations? Commit yes or no.
Common Belief:You can change AUTH_USER_MODEL anytime without problems.
Tap to reveal reality
Reality:Changing AUTH_USER_MODEL after migrations causes database conflicts and breaks authentication.
Why it matters:Ignoring this leads to complex errors and often requires resetting the database, losing data.
Quick: Does extending AbstractUser mean you must rewrite all authentication logic? Commit yes or no.
Common Belief:Extending AbstractUser requires rewriting login and permission code.
Tap to reveal reality
Reality:Extending AbstractUser keeps all built-in authentication and permission logic intact.
Why it matters:This misconception scares beginners away from customizing users, limiting app flexibility.
Quick: Does adding fields to AbstractUser automatically show them in Django admin? Commit yes or no.
Common Belief:New fields on custom user appear in admin without extra setup.
Tap to reveal reality
Reality:You must customize UserAdmin to display new fields in admin interface.
Why it matters:Without this, admins cannot edit or see new user data, causing confusion.
Quick: Is AbstractUser the only way to customize users in Django? Commit yes or no.
Common Belief:AbstractUser is the only way to customize user models.
Tap to reveal reality
Reality:You can also use AbstractBaseUser for full control, but it requires more work.
Why it matters:Knowing alternatives helps choose the right approach for your app's complexity.
Expert Zone
1
Custom user models must be defined before the first migration to avoid complex database issues.
2
Extending AbstractUser preserves compatibility with third-party Django apps expecting the default user model structure.
3
Custom user managers often need to be implemented alongside custom user models to handle user creation properly.
When NOT to use
If you need full control over authentication fields and behavior, use AbstractBaseUser instead of AbstractUser. For simple extra user info, consider a separate profile model linked by OneToOneField to the default User to avoid complexity.
Production Patterns
In production, teams define custom user models early, add only necessary fields, customize admin and forms, and write tests for authentication flows. They also implement custom user managers for creating users and superusers consistently.
Connections
Object-Oriented Programming Inheritance
Custom user models extend AbstractUser using class inheritance.
Understanding inheritance helps grasp how custom user models reuse and extend existing user features.
Database Schema Migration
Custom user models require migrations to update database schema.
Knowing migrations clarifies why changing user models mid-project is difficult and how to manage schema changes safely.
Identity and Access Management (IAM) in Security
Custom user models are part of managing user identities and permissions.
Understanding IAM principles helps design user models that support secure authentication and authorization.
Common Pitfalls
#1Changing AUTH_USER_MODEL after initial migrations.
Wrong approach:In settings.py: AUTH_USER_MODEL = 'myapp.NewUser' # After running initial migrations with default User python manage.py migrate
Correct approach:Define AUTH_USER_MODEL = 'myapp.NewUser' in settings.py before any migrations. Then run: python manage.py makemigrations python manage.py migrate
Root cause:Django creates database tables for the user model during initial migrations; changing the model later causes conflicts.
#2Not customizing admin to show new user fields.
Wrong approach:admin.site.register(CustomUser) # No custom UserAdmin class to include new fields
Correct approach:from django.contrib.auth.admin import UserAdmin class CustomUserAdmin(UserAdmin): fieldsets = UserAdmin.fieldsets + (("Extra Info", {"fields": ("phone_number",)}),) admin.site.register(CustomUser, CustomUserAdmin)
Root cause:Django admin uses UserAdmin which doesn't know about new fields unless explicitly told.
#3Using default UserCreationForm with custom user model.
Wrong approach:from django.contrib.auth.forms import UserCreationForm # Using UserCreationForm without changes for CustomUser
Correct approach:from django.contrib.auth.forms import UserCreationForm class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser fields = ('username', 'phone_number', 'email')
Root cause:Default forms expect the default User model and do not handle extra fields.
Key Takeaways
Custom user models with AbstractUser let you add fields while keeping Django's built-in user features.
Set AUTH_USER_MODEL before running migrations to avoid database conflicts.
Customize admin and forms to handle new user fields properly.
Changing user models mid-project is very difficult; plan your user model early.
Understanding inheritance and migrations is key to mastering custom user models.

Practice

(1/5)
1. What is the main reason to create a custom user model by extending AbstractUser in Django?
easy
A. To add extra fields or change user behavior while keeping Django's default features
B. To remove all default user features and start from scratch
C. To automatically create admin users without configuration
D. To avoid using migrations in the project

Solution

  1. Step 1: Understand AbstractUser purpose

    AbstractUser provides Django's default user fields and behavior as a base class.
  2. Step 2: Reason for extending AbstractUser

    Extending it allows adding custom fields or changing behavior without losing built-in features.
  3. Final Answer:

    To add extra fields or change user behavior while keeping Django's default features -> Option A
  4. Quick Check:

    Custom user model = Extend AbstractUser for extra fields [OK]
Hint: AbstractUser keeps defaults; extend it to add fields [OK]
Common Mistakes:
  • Thinking AbstractUser removes default features
  • Believing custom user models skip migrations
  • Assuming admin users are auto-created
2. Which of the following is the correct way to declare a custom user model by extending AbstractUser in Django?
easy
A. class CustomUser(AbstractBaseUser):\n pass
B. class CustomUser(User):\n pass
C. class CustomUser(models.Model):\n pass
D. class CustomUser(AbstractUser):\n pass

Solution

  1. Step 1: Identify correct base class

    The question asks for extending AbstractUser, so the class must inherit from it.
  2. Step 2: Check syntax correctness

    class CustomUser(AbstractUser):\n pass correctly defines class CustomUser(AbstractUser): pass which is valid syntax.
  3. Final Answer:

    class CustomUser(AbstractUser):\n pass -> Option D
  4. Quick Check:

    Extend AbstractUser with class CustomUser(AbstractUser) [OK]
Hint: Use AbstractUser as base class for custom user model [OK]
Common Mistakes:
  • Using User instead of AbstractUser as base
  • Inheriting directly from models.Model without user features
  • Confusing AbstractBaseUser with AbstractUser
3. Given this custom user model:
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    age = models.PositiveIntegerField(null=True, blank=True)

# settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'

What will happen if you try to create a user without specifying age?
medium
A. User creation fails due to missing age field
B. User is created successfully with age set to None
C. User is created but age defaults to 0
D. Error because age is required

Solution

  1. Step 1: Analyze age field definition

    Age is defined as PositiveIntegerField with null=True and blank=True, so it is optional.
  2. Step 2: Understand user creation behavior

    Since age is optional, creating a user without it sets age to None (null in database).
  3. Final Answer:

    User is created successfully with age set to None -> Option B
  4. Quick Check:

    Optional field with null=True allows missing value [OK]
Hint: null=True means field can be empty on creation [OK]
Common Mistakes:
  • Assuming blank=True means field is required
  • Thinking missing fields default to 0 automatically
  • Confusing null=True with default values
4. You created a custom user model extending AbstractUser and set AUTH_USER_MODEL in settings. After running migrations, you get an error about conflicting user models. What is the most likely cause?
medium
A. You set AUTH_USER_MODEL after initial migrations were created
B. You forgot to import AbstractUser in your model
C. You did not define a primary key in your custom user model
D. You used AbstractBaseUser instead of AbstractUser

Solution

  1. Step 1: Understand migration timing

    If AUTH_USER_MODEL is set after initial migrations, Django creates default user tables causing conflicts.
  2. Step 2: Identify cause of conflict error

    The conflict arises because two user models exist: default and custom, due to late setting of AUTH_USER_MODEL.
  3. Final Answer:

    You set AUTH_USER_MODEL after initial migrations were created -> Option A
  4. Quick Check:

    Set AUTH_USER_MODEL before first migration [OK]
Hint: Set AUTH_USER_MODEL before first migration to avoid conflicts [OK]
Common Mistakes:
  • Ignoring migration order importance
  • Assuming import errors cause this conflict
  • Confusing AbstractUser with AbstractBaseUser issues
5. You want to add a bio text field to your custom user model extending AbstractUser. You also want to display this bio in Django admin user list view. Which steps should you follow?
hard
A. Add bio field to model, override save() to print bio
B. Add bio field to model, no admin changes needed
C. Add bio field to model, register custom user admin with list_display including 'bio'
D. Add bio field to model, create a new admin site

Solution

  1. Step 1: Add bio field to custom user model

    Define bio = models.TextField(blank=True, null=True) in your model to store user bios.
  2. Step 2: Customize admin to show bio

    Register your custom user model admin and set list_display = ('username', 'email', 'bio') to show bio in list view.
  3. Final Answer:

    Add bio field to model, register custom user admin with list_display including 'bio' -> Option C
  4. Quick Check:

    Model field + admin list_display shows field [OK]
Hint: Add field + update admin list_display to show it [OK]
Common Mistakes:
  • Forgetting to update admin list_display
  • Overriding save() unnecessarily
  • Creating new admin site instead of customizing existing