Mixins de autenticación y autorización
Django proporciona mixins listos para usar que añaden control de acceso a cualquier CBV mediante herencia múltiple. La clave es colocarlos antes de la clase de vista en la lista de herencia.

LoginRequiredMixin
Redirige al usuario a la página de login si no está autenticado:
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView, CreateView
from django.urls import reverse_lazy
from .models import Pedido
class MisPedidosView(LoginRequiredMixin, ListView):
model = Pedido
template_name = 'pedidos/mis_pedidos.html'
login_url = '/usuarios/login/' # URL de login personalizada
redirect_field_name = 'siguiente' # Nombre del parámetro de redirección
def get_queryset(self):
return super().get_queryset().filter(usuario=self.request.user)
El valor por defecto de login_url es el definido en settings.LOGIN_URL (/accounts/login/).
PermissionRequiredMixin
Exige que el usuario tenga uno o varios permisos específicos:
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic.edit import CreateView
from .models import Producto
class ProductoCreateView(PermissionRequiredMixin, CreateView):
model = Producto
fields = ['nombre', 'precio', 'categoria']
permission_required = 'catalogo.add_producto' # Un permiso
# permission_required = ('catalogo.add_producto', 'catalogo.change_producto') # Varios
def handle_no_permission(self):
"""Personaliza la respuesta cuando el usuario no tiene permiso."""
from django.contrib import messages
messages.error(self.request, 'No tienes permiso para crear productos.')
return super().handle_no_permission()
UserPassesTestMixin
Permite definir una función de prueba personalizada para autorizar el acceso:
from django.contrib.auth.mixins import UserPassesTestMixin
from django.views.generic.edit import UpdateView
class ProductoUpdateView(UserPassesTestMixin, UpdateView):
model = Producto
fields = ['nombre', 'precio']
def test_func(self):
"""Solo el creador del producto o un admin puede editarlo."""
producto = self.get_object()
return self.request.user == producto.creado_por or self.request.user.is_staff
def get_success_url(self):
return reverse_lazy('producto-detail', kwargs={'pk': self.object.pk})
Combinar múltiples mixins
Los mixins se combinan con herencia múltiple. El orden importa: los primeros en la lista tienen prioridad en la resolución del método (MRO):
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
class GestionProductosView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
model = Producto
fields = ['nombre', 'precio', 'categoria']
permission_required = 'catalogo.add_producto'
login_url = '/login/'
success_url = reverse_lazy('producto-list')
Decoradores para vistas funcionales
Los decoradores equivalentes para vistas funcionales son:
from django.contrib.auth.decorators import login_required, permission_required
from django.views.decorators.http import require_http_methods, require_GET, require_POST
from django.shortcuts import render, get_object_or_404
from .models import Producto
@login_required
def mis_favoritos(request):
favoritos = request.user.favoritos.select_related('producto').all()
return render(request, 'catalogo/favoritos.html', {'favoritos': favoritos})
@login_required
@permission_required('catalogo.add_producto', raise_exception=True)
def crear_producto(request):
# Solo accesible para usuarios con permiso catalogo.add_producto
...
@require_http_methods(['GET', 'POST'])
def contacto(request):
if request.method == 'POST':
# Procesar formulario
...
return render(request, 'contacto.html')
Aplicar decoradores a CBV
Para aplicar decoradores de funciones a vistas basadas en clases se usa method_decorator:
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
@method_decorator(login_required, name='dispatch')
class DashboardView(TemplateView):
template_name = 'dashboard.html'
# Equivalente con mixin (más idiomático)
class DashboardView(LoginRequiredMixin, TemplateView):
template_name = 'dashboard.html'
Mixin personalizado
Es posible crear mixins propios para reutilizar comportamiento transversal:
class PropietarioMixin:
"""Mixin que filtra objetos por el usuario autenticado."""
def get_queryset(self):
return super().get_queryset().filter(creado_por=self.request.user)
class PropietarioEditMixin(PropietarioMixin):
"""Añade contexto con el nombre del propietario."""
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['propietario'] = self.request.user.get_full_name()
return context
class MisOrdenesListView(LoginRequiredMixin, PropietarioMixin, ListView):
model = Pedido
template_name = 'pedidos/lista.html'
Los mixins y decoradores de Django permiten añadir control de acceso, validaciones y comportamiento transversal a las vistas de forma declarativa y reutilizable, siguiendo el principio DRY del framework.
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
Aplicar LoginRequiredMixin para requerir autenticación en vistas basadas en clases. Usar PermissionRequiredMixin para exigir permisos concretos a nivel de vista. Implementar UserPassesTestMixin para lógica de autorización personalizada. Combinar múltiples mixins con herencia múltiple en el orden correcto. Usar los decoradores @login_required y @permission_required en vistas funcionales.