Quando iniciamos um projeto Django, é comum aceitar o modelo de usuário padrão (django.contrib.auth.models.User) sem pensar muito no futuro. Porém, conforme a aplicação cresce, surge a necessidade de adicionar campos extras, adaptar o comportamento de autenticação ou integrar regras específicas de negócio.
É nesse ponto que muitos desenvolvedores descobrem — às vezes tarde demais — que deveriam ter criado um CustomUser desde o início.
Neste guia completo, você vai entender:
-
Por que o CustomUser é tão importante
-
Diferenças entre AbstractUser e AbstractBaseUser
-
Como criar um CustomUser limpo, seguro e escalável
-
Como registrar, migrar e administrar o modelo
-
Como adaptar tudo para o Django Admin
-
Dicas avançadas e erros comuns
-
Um exemplo completo de implementação
Vamos começar pelo conceito base.
Por que Criar um CustomUser Desde o Começo?
O modelo padrão do Django funciona muito bem para projetos simples. Ele traz campos como:
-
username
-
first_name
-
last_name
-
email
-
password
Mas a maioria dos sistemas modernos exigem muito mais do que isso:
-
Usuários autenticando por e-mail, não por username
-
Perfis diferentes (cliente, vendedor, supervisor, etc.)
-
Campos adicionais como CPF, telefone, empresa, avatar
-
Regras específicas de autenticação
-
Integrações externas (SSO, OAuth, LDAP)
O problema é: trocar o modelo de usuário depois que o projeto já tem migrações é praticamente impossível sem reescrever o banco.
Ou seja: CustomUser deve ser definido no começo do projeto.
As Duas Formas de Criar um CustomUser
Django fornece duas abordagens:
1. AbstractUser – A forma mais prática
Você estende o usuário padrão do Django, mas pode adicionar campos extras ou alterar comportamentos.
Ideal quando:
-
Você só quer adicionar campos
-
Você quer usar e-mail como login
-
Quer manter a estrutura básica intacta
Exemplo:
from django.db import models
cpf = models.CharField(max_length=14, unique=True)
Essa é a abordagem recomendada para 90% dos projetos.
2. AbstractBaseUser – A forma mais poderosa (e complexa)
Aqui você recria do zero a lógica de usuário, permissões e autenticação.
Ideal quando:
-
Seu sistema não usa username nem email
-
O login é baseado em CPF, token, telefone, matrícula, etc.
-
Você precisa de um modelo extremamente específico
Exige:
-
Criar um manager customizado
-
Reescrever permissões
-
Ajustar o admin manualmente
É poderoso, mas é para quem realmente precisa.
Criando um CustomUser Modelo em Django (AbstractUser)
Abaixo está a forma mais recomendada, segura e moderna.
1. Criar o app accounts
2. Criar o modelo
Arquivo: accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import modelsclass CustomUser(AbstractUser):
email = models.EmailField(unique=True)
cpf = models.CharField(max_length=14, unique=True, null=True, blank=True) USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username'] # Campos pedidos ao criar superuser def __str__(self):
return self.emailPOR QUE USERNAME_FIELD = 'email'?
Porque estamos definindo que o login do usuário será feito via e-mail.
Criando o Manager (quando necessário)
Com AbstractUser, você nem precisa de um manager customizado.
Mas se quiser implementar validações extras:
Arquivo: accounts/managers.py
from django.contrib.auth.base_user import BaseUserManagerclass CustomUserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError("O usuário deve ter um e-mail válido.")
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("Superusuário precisa is_staff=True.")
if extra_fields.get('is_superuser') is not True:
raise ValueError("Superusuário precisa is_superuser=True.") return self.create_user(email, password, **extra_fields)Depois basta associar no modelo:
Registrar o CustomUser no settings.py
Importante: faça isso ANTES da primeira migração do projeto.
Criando as Migrações
python manage.py migrate
Adaptando o Django Admin
Django Admin não entende automaticamente um user customizado com email como login.
Precisamos registrar manualmente:
Arquivo: accounts/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUserclass CustomUserAdmin(UserAdmin):
model = CustomUser
list_display = ("email", "username", "is_staff", "is_active")
list_filter = ("is_staff", "is_active") fieldsets = (
(None, {"fields": ("email", "password")}),
("Informações pessoais", {"fields": ("username", "cpf")}),
("Permissões", {"fields": ("is_staff", "is_active", "is_superuser", "groups", "user_permissions")}),
("Datas importantes", {"fields": ("last_login", "date_joined")}),
) add_fieldsets = (
(None, {
"classes": ("wide",),
"fields": ("email", "username", "password1", "password2", "is_staff", "is_active")
}),
) search_fields = ("email",)
ordering = ("email",)admin.site.register(CustomUser, CustomUserAdmin)Agora o painel funciona normalmente.
Autenticação com email (views e forms)
Se você estiver usando django.contrib.auth.forms, pode adaptar facilmente:
from .models import CustomUser
class Meta:
model = CustomUser
fields = ["email", "username", "cpf"]
Autenticação no Login
Se você usa o AuthenticationForm, nada muda porque ele usa USERNAME_FIELD.
Se faz login manual:
Erros Comuns ao Criar CustomUser
| Erro | Causa |
|---|---|
| "You cannot change AUTH_USER_MODEL after migrations" | Você mudou o modelo após já ter migrado |
| Campanhas não aparecem no admin | Admin não foi configurado |
| Superuser não aceita username | Porque USERNAME_FIELD foi alterado |
| Login não funciona | Manager customizado incorreto |
Boas Práticas e Dicas Avançadas
• Sempre crie CustomUser no início do projeto
Mesmo que ainda não precise.
• Evite usar CPF como login
Você expõe um dado sensível e permanente.
• Adicione Index em campos de autenticação
Django já cuida disso, mas campos extras podem precisar:
• Use AbstractBaseUser apenas quando REALMENTE necessário
Para 90% dos casos, AbstractUser é a melhor abordagem.
• Documente seu processo de criação de superuser
Pois será diferente (vai pedir email ao invés de username).
Conclusão
Criar um CustomUser Model no Django não é apenas uma recomendação técnica: é uma prática essencial para qualquer sistema que pretende crescer, escalar ou se integrar com estruturas modernas de autenticação.
Fazer isso no início do projeto evita dores de cabeça futuras, elimina limitações do modelo padrão e abre a porta para funcionalidades avançadas como:
-
Login com email
-
Perfis personalizados
-
Campos adicionais
-
Sistemas multiusuário complexos
Se você está começando um novo projeto Django agora — crie seu CustomUser imediatamente.