Django - Sending E-mails
Django - Sending E-mails
Section titled “Django - Sending E-mails”Django provides a convenient and robust API for sending emails, abstracting away the low-level details of SMTP (Simple Mail Transfer Protocol).
Configuration (settings.py)
Section titled “Configuration (settings.py)”Before sending emails, you need to configure the email backend and connection details in your project’s settings.py file:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_HOST = 'smtp.example.com' # Your SMTP server address (e.g., smtp.gmail.com)EMAIL_PORT = 587 # Common port for TLSEMAIL_USE_TLS = True # Use TLS (Transport Layer Security) - Recommended# EMAIL_USE_SSL = False # Use SSL (Secure Sockets Layer) - Less common now than TLSEMAIL_HOST_USER = 'your_email@example.com' # Your SMTP usernameEMAIL_HOST_PASSWORD = 'your_app_password' # Your SMTP password or App Password (e.g., for Gmail)Key Settings:
Section titled “Key Settings:”EMAIL_BACKEND: Specifies the backend to use.smtp.EmailBackendis standard. Others includeconsole.EmailBackend(prints emails to console, great for development),filebased.EmailBackend(saves emails to files), andlocmem.EmailBackend(stores emails in memory for testing).EMAIL_HOST: The hostname or IP address of your SMTP server.EMAIL_PORT: The port the SMTP server listens on (e.g., 587 for TLS, 465 for SSL, 25 for unencrypted - not recommended).EMAIL_USE_TLS/EMAIL_USE_SSL: Boolean flags indicating whether to use a secure connection (TLS is generally preferred over SSL). They are mutually exclusive.EMAIL_HOST_USER: Username for SMTP authentication.EMAIL_HOST_PASSWORD: Password for SMTP authentication. Security Note: Avoid hardcoding credentials directly insettings.py. Use environment variables or a secrets management tool.DEFAULT_FROM_EMAIL: (Optional) Sets a default ‘From’ address if not specified when sending mail.settings.py->DEFAULT_FROM_EMAIL = 'webmaster@example.com'
Sending a Simple E-mail (send_mail)
Section titled “Sending a Simple E-mail (send_mail)”The send_mail function is the quickest way to send a basic email.
# In a view or management commandfrom django.core.mail import send_mailfrom django.http import HttpResponse
def send_simple_email_view(request): try: num_sent = send_mail( 'Test Subject', 'This is the email body message.', 'from@example.com', # Sender's email (often matches EMAIL_HOST_USER or DEFAULT_FROM_EMAIL) ['recipient1@example.com', 'recipient2@example.com'], # List of recipients fail_silently=False, # If False (default), raises SMTPException on error ) return HttpResponse(f'{num_sent} email(s) sent successfully.') except Exception as e: # Log the error e return HttpResponse(f'Error sending email: {e}', status=500)send_mail Parameters:
Section titled “send_mail Parameters:”subject: Email subject line (string).message: Plain text body of the email (string).from_email: Sender’s email address (string).recipient_list: A list or tuple of recipient email addresses (strings).fail_silently: Boolean. IfFalse(default), exceptions are raised. IfTrue, errors are ignored silently (generally not recommended unless you have specific error handling).auth_user,auth_password: Overridesettings.pycredentials.connection: Use a specific email backend connection.html_message: Provide an HTML version of the email body. If provided, the email becomesmultipart/alternative, and email clients will display the HTML version if possible, falling back to the plain textmessage.
Sending Multiple Emails Efficiently (send_mass_mail)
Section titled “Sending Multiple Emails Efficiently (send_mass_mail)”To send multiple emails using a single connection (more efficient), use send_mass_mail.
from django.core.mail import send_mass_mailfrom django.http import HttpResponse
def send_mass_email_view(request): message1 = ('Subject 1', 'Message body 1', 'from@example.com', ['recipient1@example.com']) message2 = ('Subject 2', 'Message body 2', 'from@example.com', ['recipient_other@example.com']) datatuple = (message1, message2)
try: num_sent = send_mass_mail(datatuple, fail_silently=False) return HttpResponse(f'{num_sent} email(s) sent successfully using mass mail.') except Exception as e: # Log the error e return HttpResponse(f'Error sending mass email: {e}', status=500)send_mass_mail takes a tuple (datatuple) where each element is a tuple in the format (subject, message, from_email, recipient_list). Other arguments (fail_silently, auth_user, etc.) are similar to send_mail.
Sending HTML Emails and Attachments (EmailMessage)
Section titled “Sending HTML Emails and Attachments (EmailMessage)”For more control, including HTML content, attachments, and headers, use the EmailMessage class.
from django.core.mail import EmailMessagefrom django.http import HttpResponseimport osfrom django.conf import settings # To access BASE_DIR for attachments
def send_html_email_with_attachment_view(request): subject = 'Email with HTML and Attachment' text_content = 'This is an important message.' # Plain text fallback html_content = '<p>This is an **important** message in HTML.</p>' from_email = 'from@example.com' to = ['recipient@example.com']
try: email = EmailMessage(subject, text_content, from_email, to) email.attach_alternative(html_content, "text/html")
# Optional: Attach a file # attachment_path = os.path.join(settings.BASE_DIR, 'path/to/your/file.pdf') # if os.path.exists(attachment_path): # email.attach_file(attachment_path)
# Or attach content directly: # email.attach('filename.txt', 'File content here', 'text/plain')
num_sent = email.send() return HttpResponse(f'{num_sent} HTML email(s) sent.')
except Exception as e: # Log the error e return HttpResponse(f'Error sending HTML email: {e}', status=500)EmailMessage methods:
Section titled “EmailMessage methods:”- Initialization:
EmailMessage(subject, body, from_email, to, bcc=None, connection=None, attachments=None, headers=None, cc=None, reply_to=None) send(fail_silently=False): Sends the email.attach(filename, content, mimetype): Attaches content generated in code.attach_file(path, mimetype=None): Attaches a file from the filesystem.attach_alternative(content, mimetype): Adds alternative content types (commonly used fortext/html).
Emails to Admins and Managers (mail_admins, mail_managers)
Section titled “Emails to Admins and Managers (mail_admins, mail_managers)”Django provides shortcuts to email administrators and managers defined in settings.py:
ADMINS = [('Admin Name', 'admin@example.com'),]MANAGERS = [('Manager Name', 'manager@example.com'),]from django.core.mail import mail_admins, mail_managersfrom django.http import HttpResponse
def notify_admins_view(request): try: mail_admins('Site Critical Alert', 'The site needs immediate attention!', fail_silently=False) # mail_managers('Site Update', 'Content needs review.', fail_silently=False) return HttpResponse('Notification email sent.') except Exception as e: return HttpResponse(f'Error sending admin/manager email: {e}', status=500)These functions prepend the EMAIL_SUBJECT_PREFIX setting (default: [Django] ) to the subject.
Development and Testing
Section titled “Development and Testing”During development, avoid sending real emails. Use the console or file-based backend:
# settings.py (for development)EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'Alternatively, use tools like MailHog or Mailtrap which set up a local fake SMTP server to catch outgoing emails for inspection without actually sending them.
Asynchronous Email Sending
Section titled “Asynchronous Email Sending”Sending emails can sometimes be slow and block the web request. For production applications, especially those sending emails frequently or during user requests, it’s highly recommended to send emails asynchronously using a task queue like Celery with Redis or RabbitMQ. This offloads the email sending task to a background worker process, keeping your web application responsive.