Custom User Model

A custom user model is a model class you define to replace Django's built-in auth.User, registered through the AUTH_USER_MODEL setting, so you can add fields, log in by email, and control how users are created.

Learn Custom User Model in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll compare AbstractUser with AbstractBaseUser, set AUTH_USER_MODEL the right way, switch login from username to email, and write a custom UserManager that powers create_user and create_superuser.

Django gives you two starting points. Subclassing AbstractUser inherits all the standard fields — username, email, password, is_staff, is_active, and the permission relations — so you only add what's new. Subclassing AbstractBaseUser gives you almost nothing but the password machinery, so you define the identifier field, the manager, and the permission mix-in yourself. For most projects, AbstractUser plus a couple of extra fields is the right call.

Here's the simplest possible custom user — just add a field:

Defining the class is not enough — you must tell Django to use it with the AUTH_USER_MODEL setting. This is best done before your first migration , because swapping the user model after foreign keys to it already exist is extremely painful. Always reference settings.AUTH_USER_MODEL in your own foreign keys so your code never hardcodes the user class.

To log in by email with no username, you subclass AbstractBaseUser , make email the unique identifier, set USERNAME_FIELD = "email" , and attach a custom UserManager . The manager's create_user and create_superuser methods enforce the rules: require an email, normalize it, hash the password, and set the staff/superuser flags. This is exactly what createsuperuser calls on the command line.

The AUTH_USER_MODEL setting uses the form "app_label.ModelName" . Replace the blank so the project uses the User model in the accounts app.

❌ I changed AUTH_USER_MODEL after migrating and everything broke

Django can't swap the user model once tables reference it.

✅ Fix: set AUTH_USER_MODEL before the first migration. If you're stuck, the cleanest path is a fresh database during development.

❌ ForeignKey to User causes circular or stale references

You imported the user class directly instead of the setting.

✅ Fix: use settings.AUTH_USER_MODEL in foreign keys and get_user_model() in code.

❌ createsuperuser fails with "Manager isn't available"

Your model has no manager defining create_superuser , or USERNAME_FIELD is wrong.

✅ Fix: attach a UserManager as objects and set USERNAME_FIELD to your login field.

Write a manager with create_user and create_superuser that requires an email, normalizes it, and enforces that a superuser is also staff.

Lesson complete — you own the user model!

You can choose between AbstractUser and AbstractBaseUser, set AUTH_USER_MODEL at project start, switch login from username to email, and write a UserManager whose create_user and create_superuser enforce your rules.

🚀 Up next: Formsets & Inline Formsets — handle many forms at once and edit related objects together.

Practice quiz

Which setting tells Django to use your custom user class?

  • USER_MODEL
  • AUTH_USER_MODEL
  • DEFAULT_USER
  • CUSTOM_USER

Answer: AUTH_USER_MODEL. AUTH_USER_MODEL, written as 'app_label.ModelName', points Django at your custom user model.

What format does AUTH_USER_MODEL use?

  • The full import path like accounts.models.User
  • Just the model name like User
  • 'app_label.ModelName' like 'accounts.User'
  • A reference to the class object itself

Answer: 'app_label.ModelName' like 'accounts.User'. AUTH_USER_MODEL uses the 'app_label.ModelName' string, e.g. 'accounts.User'.

When subclassing AbstractUser, what do you get for free?

  • Nothing but password and last_login
  • All standard fields: username, email, password, is_staff, etc.
  • Only an email field
  • A REST API for users

Answer: All standard fields: username, email, password, is_staff, etc.. AbstractUser inherits the full set of standard user fields, so you just add extras.

When should you reach for AbstractBaseUser instead of AbstractUser?

  • When you want the standard fields plus extras
  • When you only need to add one field
  • For every project by default
  • When you need full control, e.g. email-only login with no username

Answer: When you need full control, e.g. email-only login with no username. AbstractBaseUser is minimal and used when you want full control over the identifier and fields.

Why should you set AUTH_USER_MODEL before the first migration?

  • Swapping the user model after foreign keys exist is extremely painful
  • Django deletes the default user otherwise
  • It speeds up migrations
  • Settings can only be changed once

Answer: Swapping the user model after foreign keys exist is extremely painful. Once tables hold foreign keys to the user, Django cannot cleanly swap the user model.

What should you reference in your foreign keys to the user?

  • A direct import of the User class
  • settings.AUTH_USER_MODEL
  • auth.User always
  • get_user_model() at module level

Answer: settings.AUTH_USER_MODEL. Use settings.AUTH_USER_MODEL in ForeignKey so the project stays free to swap the user class.

How do you get the active user class in code at runtime?

  • from django.contrib.auth.models import User
  • settings.AUTH_USER_MODEL()
  • get_user_model()
  • User.objects.model()

Answer: get_user_model(). get_user_model() returns whatever class AUTH_USER_MODEL points to.

Which attribute names the field used to log in?

  • LOGIN_FIELD
  • PRIMARY_FIELD
  • IDENTIFIER
  • USERNAME_FIELD

Answer: USERNAME_FIELD. USERNAME_FIELD names the field (e.g. 'email') used as the login identifier.

Which methods must a custom UserManager provide?

  • create_user and create_superuser
  • save and delete
  • login and logout
  • get and filter

Answer: create_user and create_superuser. Django expects create_user and create_superuser on the manager; createsuperuser calls the latter.

Should the USERNAME_FIELD also be listed in REQUIRED_FIELDS?

  • Yes, always include it
  • No — Django asks for USERNAME_FIELD automatically
  • Only for superusers
  • Only if it is the email

Answer: No — Django asks for USERNAME_FIELD automatically. REQUIRED_FIELDS holds extra prompts; Django already asks for USERNAME_FIELD, so don't duplicate it.