Registro de usuarios y perfil

Intermedio
Django
Django
Actualizado: 18/04/2026

Formulario de registro

Django proporciona UserCreationForm como punto de partida para el registro. Se puede extender para añadir campos adicionales:

# usuarios/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import get_user_model

Usuario = get_user_model()

class FormularioRegistro(UserCreationForm):
    email = forms.EmailField(required=True, help_text='Requerido. Recibirás notificaciones aquí.')
    nombre = forms.CharField(max_length=50, required=True)
    apellidos = forms.CharField(max_length=100, required=False)
    acepto_terminos = forms.BooleanField(
        required=True,
        error_messages={'required': 'Debes aceptar los términos y condiciones.'}
    )

    class Meta(UserCreationForm.Meta):
        model = Usuario
        fields = ['username', 'email', 'nombre', 'apellidos', 'password1', 'password2']

    def clean_email(self):
        email = self.cleaned_data.get('email').lower()
        if Usuario.objects.filter(email=email).exists():
            raise forms.ValidationError('Ya existe una cuenta con este email.')
        return email

    def save(self, commit=True):
        usuario = super().save(commit=False)
        usuario.email = self.cleaned_data['email']
        usuario.first_name = self.cleaned_data.get('nombre', '')
        usuario.last_name = self.cleaned_data.get('apellidos', '')
        if commit:
            usuario.save()
        return usuario

Diagrama conceptual de Registro de usuarios y perfil

Vista de registro

# usuarios/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.contrib import messages
from .forms import FormularioRegistro

def registro(request):
    if request.user.is_authenticated:
        return redirect('dashboard')

    if request.method == 'POST':
        form = FormularioRegistro(request.POST)
        if form.is_valid():
            usuario = form.save()
            login(request, usuario)  # Login automático tras registro
            messages.success(
                request,
                f'¡Bienvenido/a, {usuario.get_full_name() or usuario.username}! Tu cuenta ha sido creada.'
            )
            return redirect('dashboard')
    else:
        form = FormularioRegistro()

    return render(request, 'usuarios/registro.html', {'form': form})

Modelo Perfil con señal post_save

Para datos adicionales del usuario que no caben en el modelo User, se crea un modelo Perfil relacionado y se crea automáticamente al crear el usuario:

# usuarios/models.py
from django.db import models
from django.conf import settings

class Perfil(models.Model):
    usuario = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='perfil'
    )
    avatar = models.ImageField(upload_to='avatares/', blank=True, null=True)
    bio = models.TextField(blank=True, max_length=500)
    ciudad = models.CharField(max_length=100, blank=True)
    sitio_web = models.URLField(blank=True)
    fecha_nacimiento = models.DateField(null=True, blank=True)

    def __str__(self):
        return f'Perfil de {self.usuario.username}'

# usuarios/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from .models import Perfil

Usuario = get_user_model()

@receiver(post_save, sender=Usuario)
def crear_o_actualizar_perfil(sender, instance, created, **kwargs):
    if created:
        Perfil.objects.create(usuario=instance)
    else:
        # Guardar el perfil si ya existe (para sincronizar cambios)
        if hasattr(instance, 'perfil'):
            instance.perfil.save()

Conecta las señales en AppConfig:

# usuarios/apps.py
from django.apps import AppConfig

class UsuariosConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'usuarios'

    def ready(self):
        import usuarios.signals  # Conecta las señales al iniciar la app

Vista de edición de perfil

# usuarios/forms.py
class FormularioPerfil(forms.ModelForm):
    class Meta:
        model = Perfil
        fields = ['avatar', 'bio', 'ciudad', 'sitio_web', 'fecha_nacimiento']
        widgets = {
            'fecha_nacimiento': forms.DateInput(attrs={'type': 'date'}),
            'bio': forms.Textarea(attrs={'rows': 3}),
        }

class FormularioDatosUsuario(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name', 'email']

# usuarios/views.py
from django.contrib.auth.decorators import login_required
from .forms import FormularioPerfil, FormularioDatosUsuario

@login_required
def editar_perfil(request):
    if request.method == 'POST':
        form_usuario = FormularioDatosUsuario(request.POST, instance=request.user)
        form_perfil = FormularioPerfil(request.POST, request.FILES, instance=request.user.perfil)

        if form_usuario.is_valid() and form_perfil.is_valid():
            form_usuario.save()
            form_perfil.save()
            messages.success(request, 'Perfil actualizado correctamente.')
            return redirect('mi-perfil')
    else:
        form_usuario = FormularioDatosUsuario(instance=request.user)
        form_perfil = FormularioPerfil(instance=request.user.perfil)

    return render(request, 'usuarios/editar_perfil.html', {
        'form_usuario': form_usuario,
        'form_perfil': form_perfil,
    })

@login_required
def mi_perfil(request):
    return render(request, 'usuarios/perfil.html', {'perfil': request.user.perfil})
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Django es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Django

Explora más contenido relacionado con Django y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Crear un formulario de registro extendiendo UserCreationForm. Implementar la vista de registro con validación y redirección al login. Crear automáticamente el perfil del usuario con la señal post_save. Implementar la vista de perfil con edición de datos personales. Permitir al usuario cambiar su contraseña desde su perfil.