← Back to Django Course | Chapter 10: Authentication & Authorization | Lesson 12 of 12

Sending Emails with Django

Django's mail system is like having a built-in mailbox slot — you drop in a message and Django handles getting it sent.

Sending an Email

send_mail() takes a subject, plain-text message, sender address, and a list of recipients, and returns how many were sent successfully.

Example: Sending an Email

send_mail() returns 1 if the message was accepted for delivery by the configured backend, 0 otherwise.

markup
from django.core.mail import send_mail

def send_welcome_email(user_email):
    send_mail(
        'Welcome!',
        'Thanks for joining our site.',
        '[email protected]',
        [user_email],
    )
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

The Console Email Backend

During development, the console backend prints emails to the terminal instead of actually sending them — no real mail server needed.

Note: This is the safest way to test email-sending code without spamming real inboxes.

Example: The Console Email Backend

Every call to send_mail() will now print the full email content to your terminal instead of delivering it.

markup
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Calling send_mail() from a View

A view can trigger an email as a side effect of another action, like after a successful registration.

Example: Calling send_mail() from a View

This keeps the email-sending logic small and reusable, called right after the account is actually created.

markup
from django.core.mail import send_mail
from django.shortcuts import redirect

def register_and_notify(request, new_user):
    send_mail(
        'Account Created',
        f'Welcome, {new_user.username}!',
        '[email protected]',
        [new_user.email],
    )
    return redirect('home')
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Forgetting to configure EMAIL_BACKEND, causing Django to silently try (and fail) to connect to a real mail server during development.
  2. Hardcoding real SMTP credentials directly in settings.py instead of loading them from environment variables.
  3. Not checking the return value of send_mail(), which returns the number of successfully delivered messages.
Chapter Summary
  • send_mail() is Django's built-in shortcut for sending email from a view.
  • EMAIL_BACKEND controls where mail actually goes — the console backend prints emails to the terminal during development.
  • send_mail() takes a subject, message, from address, and a list of recipient addresses.
  • Production email credentials should come from environment variables, never be hardcoded.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.