Using email instead of a username for login is more user-friendly and often preferred in modern applications. Django supports this, but it requires a custom user model. Here's how to set it up cleanly and correctly.
β Step 1: Create a Custom User Model
In your core/models.py (or any appropriate app), define a user model using AbstractBaseUser and PermissionsMixin:
from django.contrib.auth.models import ( AbstractBaseUser, BaseUserManager, PermissionsMixin, ) from django.db import models class UserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): if not email: raise ValueError("Email is required") email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save() return user def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault("is_staff", True) extra_fields.setdefault("is_superuser", True) return self.create_user(email, password, **extra_fields) class AppUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True) full_name = models.CharField(max_length=150) phone_number = models.CharField(max_length=20, blank=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = "email" REQUIRED_FIELDS = ["full_name"] def __str__(self): return self.email β Step 2: Point Django to Your New User Model
In settings.py:
AUTH_USER_MODEL = "core.AppUser" Make sure this is set before running any migrations.
β Step 3: Create and Apply Migrations
python manage.py makemigrations core python manage.py migrate This sets up your database using the email field as the login ID.
β
Step 4: Use get_user_model() Everywhere
Avoid importing User directly. Use this in views, tests, and signals:
from django.contrib.auth import get_user_model User = get_user_model() Example usage in tests:
User.objects.create_user(email="user@example.com", password="testpass") β Step 5: Create Superuser with Email
When creating a superuser via script or CLI, use:
python manage.py createsuperuser --email admin@example.com --full_name "Admin" If you use --noinput, pass in the --email and --full_name values explicitly in your script.
β Done
You now have a Django project where email is the unique identifier for login. This setup is clean, minimal, and aligns with real-world authentication flows.
Top comments (0)