How to Send Emails with Attachments in Django

Sending an email with an attachment in Django involves using Django’s EmailMessage or EmailMultiAlternatives class along with the EmailBackend.

1. Setup Email Backend:

Make sure you have your email backend configured in settings.py. For example, to use Gmail, you might have something like:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'your-email-password'

2. Create the Email Sending Function:

You can use Django’s EmailMessage class to send an email with attachments.

from django.core.mail import EmailMessage

def send_email_with_attachment(subject, body, to_email, attachment_path):
    email = EmailMessage(
        subject,
        body,
        '[email protected]',  # From email
        [to_email],  # To email
    )
    # Attach the file
    email.attach_file(attachment_path)
    # Send the email
    email.send()
  • subject: The subject line of the email.
  • body: The body of the email.
  • to_email: The recipient’s email address.
  • attachment_path: The path to the file you want to attach.

3. Call the Function

You can call this function from anywhere in your Django project, such as in a view or a management command.

def my_view(request):
    # Example call to send_email_with_attachment
    send_email_with_attachment(
        'Subject Here',
        'Body of the email.',
        '[email protected]',
        '/path/to/your/attachment.pdf'
    )
    return HttpResponse('Email sent!')

4. Handling Errors

Make sure to handle potential errors, such as file not found or email sending failures.

from django.core.mail import BadHeaderError
from django.core.exceptions import SuspiciousOperation

def send_email_with_attachment(subject, body, to_email, attachment_path):
    try:
        email = EmailMessage(
            subject,
            body,
            '[email protected]',
            [to_email],
        )
        email.attach_file(attachment_path)
        email.send()
    except BadHeaderError:
        # Handle invalid header error
        raise SuspiciousOperation("Invalid header found.")
    except FileNotFoundError:
        # Handle file not found error
        print("Attachment file not found.")
    except Exception as e:
        # Handle other exceptions
        print(f"An error occurred: {e}")

Now it Depending on your requirements, you might need to customize this further, such as adding HTML content, multiple attachments, or error logging.