Envío de correos en Django mediante Mailtrap

Video thumbnail

Enviar correos electrónicos desde Django es una de esas tareas que tarde o temprano todos necesitamos implementar. Ya sea para confirmar cuentas, recuperar contraseñas o notificar acciones al usuario, configurar el envío de correos correctamente es esencial así como otras tareas más avanzadas como crear chats con comunicaciones fullduplex con Websockets y Django.

Necesitaremos enviar emails para poder probar el módulo de reiniciar la contraseña; la configuración de un servidor de correos está fuera del alcance de este libro y debido a que no todos los lectores están en la capacidad de configurar uno propio o de ya tener uno servidor de correos, emplearemos un servicio que permite simular el envío de emails:

https://mailtrap.io/

¿Por qué necesitas enviar correos en una aplicación Django?

Django facilita enormemente la comunicación con usuarios a través del correo electrónico. Algunos escenarios comunes son:

  • Confirmación de registro o verificación de cuenta.
  • Recuperación o restablecimiento de contraseñas.
  • Notificaciones de eventos, pedidos o cambios importantes.

Configuración inicial del envío de correos en Django

Una vez registrado y creado un servidor de desarrollo, debemos de configurar las siguientes variables:

customlogin\settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.mailtrap.io'
EMAIL_HOST_USER = '<YourUserMailTrap>'
EMAIL_HOST_PASSWORD = '<YourPasswordMailTrap>'
EMAIL_PORT = '2525'
EMAIL_USE_TLS = True

Las cuales determinan el host, usuario, contraseña y puerto del servidor de correos respectivamente; con esto, estamos listos para que la aplicación pueda enviar correos.

Usar Mailtrap para pruebas de envío de correos

Mailtrap es ideal para probar el envío sin afectar usuarios reales. Lo que hace es interceptar los correos y mostrarlos en una bandeja de entrada de desarrollo.

Pasos rápidos:

  • Regístrate en mailtrap.io
  • Crea un Inbox o entorno de desarrollo.
  • Copia las credenciales SMTP que te proporciona.

Pégalos en el settings.py de tu proyecto (como en el bloque anterior).

De esta forma, cualquier correo que Django intente enviar llegará a tu bandeja de pruebas en Mailtrap, sin riesgo ni necesidad de un servidor real.

Enviar tu primer correo desde Django

Una vez configurado el servidor, puedes enviar tu primer correo con la función send_mail().

from django.core.mail import send_mail
send_mail(
   subject='Prueba de correo desde Django',
   message='¡Hola! Este es un correo de prueba enviado desde Django.',
   from_email='no-reply@miapp.com',
   recipient_list=['usuario@correo.com'],
   fail_silently=False,
)

Qué hace cada parámetro:

  • subject: asunto del correo.
  • message: contenido del mensaje.
  • from_email: dirección del remitente.
  • recipient_list: lista de destinatarios.
  • fail_silently: si es True, no muestra errores al fallar.

✅ Tip: siempre prueba con varios destinatarios falsos y verifica que Mailtrap los reciba correctamente.

Enviar correos HTML y con archivos adjuntos

Lo ideal es utilizar el motor de plantillas de Django para diseñar el correo en un archivo separado. Esto nos permite mantener el código limpio y organizado.

2. Importar el cargador de plantillas

Primero, necesitamos importar render_to_string para convertir un archivo .html en una cadena de texto que el servicio de correo pueda procesar.

from django.template.loader import render_to_string

3. Crear el Template del Correo

Dentro de tu carpeta de templates, crea una subcarpeta llamada email y dentro un archivo llamado common.html. Aquí puedes usar todo lo que ya conoces sobre el motor de plantillas:

<!DOCTYPE html>
<html>
<head>
   <style>
       h1 { color: blue; }
       p { font-family: Arial, sans-serif; }
   </style>
</head>
<body>
   <h1>{{ titulo }}</h1>
   <p>{{ contenido }}</p>
</body>
</html>

Y lo procesas:

from django.template.loader import render_to_string
# Generamos el HTML a partir de la plantilla
html_content = render_to_string('emails/promocion.html', {
   'titulo': 'Oferta especial',
   'contenido': 'Hola, aprovecha este descuento.'
})
# Enviamos el email usando el parámetro html_message
send_mail(
   'Asunto dinámico',
   'Mensaje en texto plano (respaldo)',
   'de@ejemplo.com',
   ['para@ejemplo.com'],
   html_message=html_content,
)

Integración con Signals

Un uso muy potente para el envío de correos es integrarlo con los Signals. Esto permite automatizar el envío cuando ocurre un evento específico, por ejemplo, cuando un usuario compra un curso.

¿Por qué usar Signals para enviar correos?

Podrías pensar que es mejor colocar la lógica del envío directamente en la vista donde se registra la compra, pero existen varias razones para preferir una señal:

  • Múltiples vías de creación: Un curso puede registrarse manualmente desde el Django Admin, mediante una API (Django REST Framework) o a través de una vista tradicional.
  • Evitar repetición: En lugar de llamar a la función de envío en tres sitios distintos, la señal centraliza la lógica.
  • Modularización: Separas la lógica administrativa (registrar en la BD) de la lógica informativa o de verificación (enviar el email).
from django.core.mail import send_mail
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=MiModelo)
def enviar_notificacion(sender, instance, created, **kwargs):
    if created:
        send_mail(
            '¡Felicidades!',
            'Te has registrado correctamente.',
            'tu-email@ejemplo.com',
            [instance.email_cliente],
            fail_silently=False,
        )

Consejos y buenas prácticas para entornos de producción

Cuando tu aplicación esté lista para enviar correos reales, ten en cuenta lo siguiente:

  • Usa variables de entorno (por ejemplo, con python-decouple) para no exponer credenciales en el código.
  • Activa TLS o SSL según lo requiera tu proveedor SMTP.
  • Controla el envío masivo para no ser marcado como spam.
  • Servicios recomendados: SendGrid, Amazon SES, Gmail SMTP (con App Passwords).

Errores comunes al enviar correos en Django (y cómo solucionarlos)

  • Error    Causa probable    Solución
  • smtplib.SMTPAuthenticationError    Usuario o contraseña incorrectos    Revisa credenciales o usa variables de entorno
  • ConnectionRefusedError    Puerto incorrecto o servidor caído    Verifica EMAIL_PORT y conexión
  • TimeoutError    Problemas de red o firewall    Prueba en otro entorno o cambia el puerto
  • Correo no llega    Bloqueo de Gmail o servidor real    Usa Mailtrap o revisa logs SMTP

Conclusión y próximos pasos

Enviar correos en Django es más sencillo de lo que parece si entiendes la estructura de settings.py y usas herramientas adecuadas para cada fase.

Mailtrap es tu mejor aliado para pruebas seguras; luego puedes pasar a un servicio SMTP real en producción.

Sigue practicando con:

  • Adjuntos y plantillas personalizadas.
  • Mensajes asíncronos con Celery.
  • Integración con servicios externos como SendGrid o SES.

En resumen, con unas pocas líneas de código y un entorno bien configurado, puedes profesionalizar el envío de correos en Django sin complicaciones.

Preguntas frecuentes

  • ¿Puedo usar Gmail para enviar correos desde Django?
    • Sí, pero debes generar una contraseña de aplicación y habilitar TLS en el puerto 587.
  • ¿Qué diferencia hay entre send_mail y EmailMessage?
    • send_mail es más simple; EmailMessage permite HTML, adjuntos y mayor personalización.
  • ¿Cómo probar sin servidor real?
    • Con Mailtrap: intercepta y muestra los correos de desarrollo sin riesgo.
  • ¿Por qué no se envía mi correo en Django?
    • Verifica tus credenciales, puerto SMTP y que no tengas bloqueos de red.

Siguiente paso, Implementando un campo de búsqueda y filtros con formularios en Django para que puedas filtrar esos correos electrónicos.

Acepto recibir anuncios de interes sobre este Blog.

Emplearemos el servicio de Mailtrap para enviar mensajes de pruebas, configuraremos Mailtrap y la app de Django para probar la recuperación de contraseñas.

| 👤 Andrés Cruz

🇺🇸 In english