In today's interconnected world, email remains a vital means of communication for businesses, organizations, and individuals. In this article, we will discuss how to send emails using Django.
Configuring the project
First, let us discuss the configuration process. To begin, locate the settings.py
file within your project directory, and proceed to append the following lines of code:
1EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
2EMAIL_HOST = 'smtp.gmail.com'
3EMAIL_HOST_USER = '<your_email>'
4EMAIL_HOST_PASSWORD = '<your_password>' # Note that this should be the App password rather than your Google account password
5EMAIL_PORT = 465
6EMAIL_USE_SSL = True
In the example provided, we're utilizing the default SMTP backend and Gmail service to handle email sending. To personalize it for your needs, simply replace <your_email>
with your email address, and <your_password>
with the App password generated from your Google account.
To generate the App password, you can follow these steps:
- Visit the Google Account page.
- Navigate to the Security section and select 2-Step Verification. You must turn on the 2-Step Verification before proceeding to the next step.
- Under App passwords, choose the Mail app and select the device for which you want to generate the app password.
- Click the Generate button to create the app password.
Following these steps will give you a secure and personalized configuration for sending emails in your Django application.
Sending your first email
Next, you can proceed to send a test email. Go to views.py:
1from django.shortcuts import render
2from django.http import HttpResponse
3from django.core.mail import send_mail
4
5# Create your views here.
6
7
8def send(request):
9 send_mail(
10 "Subject here",
11 "Here is the message.",
12 "from@example.com",
13 ["<your_email_address>"],
14 fail_silently=False,
15 )
16 return HttpResponse("Email sent.")
17
This example uses the default send_mail()
method to send an email, which takes the following parameters:
subject
: The subject of the email.message
: The actual content of the email.from_email
: The email address that this email is sent from. If not set, Django will use the value of theDEFAULT_FROM_EMAIL
setting. You may add this setting to thesettings.py
file.recipient_list
: A list of email addresses. Each member ofrecipient_list
will see the other recipients in the “To:” field of the email message.fail_silently
: A boolean value. When it’sFalse
,send_mail()
will raise ansmtplib.SMTPException
if an error occurs.
In order to test this code, create a route that points to this send()
view.
1from app import views
2
3urlpatterns = [
4 path('send/', views.send),
5]
Start the Django application and send a request to http://127.0.0.1:8000/send/
.
1curl http://127.0.0.1:8000/send/
Wait a few seconds, and you should get the following email in your inbox.
Sending emails in bulk
To send multiple emails together, you may use the send_mass_mail()
method instead.
1from django.shortcuts import render
2from django.http import HttpResponse
3from django.core.mail import send_mass_mail
4
5# Create your views here.
6
7
8def send(request):
9
10 mails = (
11 ("Subject #1", "Message #1", "from@example.com", ["<email_address>"]),
12 ("Subject #2", "Message #2", "from@example.com", ["<email_address>"]),
13 ("Subject #3", "Message #3", "from@example.com", ["<email_address>"]),
14 ("Subject #4", "Message #4", "from@example.com", ["<email_address>"]),
15 ("Subject #5", "Message #5", "from@example.com", ["<email_address>"]),
16 )
17 send_mass_mail(mails)
18 return HttpResponse("Emails sent.")
19
The <email_address>
placeholder can be different values. Send a request to the route, and you should receive five emails.
Sending emails with attachments
Both send_mail()
and send_mass_mail()
methods are, in fact, wrappers using the EmailMessage
class. They provide shortcuts allowing us to send emails more efficiently. However, if you want to do something more complex, for example, an email with attachments, you'll have to use the EmailMessage
class directly.
1def send_attachment(request):
2 email = EmailMessage(
3 "Hello",
4 "Body goes here",
5 "from@example.com",
6 ["huericnan@gmail.com"],
7 )
8
9 image_path = os.path.join('files/image.png')
10 with open(image_path, 'rb') as f:
11 img_data = f.read()
12
13 email.attach("image.png", img_data, "image/png")
14
15 email.send()
16
17 return HttpResponse("Email sent with attachment.")
The attach()
method takes three arguments: filename
, content
, and mimetype
. filename
is the name of the file attachment as it will appear in the email, content
is the binary data that will be contained inside the attachment and mimetype
is the optional MIME type for the attachment.
Alternatively, you can create an attachment directly using a file in your filesystem without having to read the binary data first.
1email.attach_file("path/to/file")
Sending HTML emails
Nowadays, most emails are crafted with HTML to make them more appealing to the readers. And Django also provides a way to send emails written in HTML.
1from django.core.mail import EmailMultiAlternatives
2
3def send_html(request):
4 subject, from_email, to = "Hello!", "from@example.com", "huericnan@gmail.com"
5 text_content = "This is a message written in HTML."
6 html_content = "<p>This is an <strong>important</strong> message.</p>"
7 email = EmailMultiAlternatives(subject, text_content, from_email, [to])
8 email.attach_alternative(html_content, "text/html")
9 email.send()
10
11 return HttpResponse("HTML email sent.")
The EmailMultiAlternatives
class offers a way to send emails crafted in different formats. Notice that, in this example, there is a text_content
and a html_content
. By default, the body of the email will be html_content
. However, if the recipient cannot open HTML, the text_content
will be displayed instead.
Creating templates for your emails
Sometimes, the email you send to different recipients might be different. For example, if you send account confirmation emails to different users, their usernames should differ. In this case, you should create a template for the emails. First, create a template
directory for your app:
1.
2├── app
3│ ├── admin.py
4│ ├── apps.py
5│ ├── __init__.py
6│ ├── migrations
7│ ├── models.py
8│ ├── templates
9│ │ ├── email.html
10│ │ └── email.txt
11│ ├── tests.py
12│ └── views.py
13├── djangoEmail
14├── files
15└── manage.py
email.txt
1Congratulations, {{username}}! Your account has been successfully activated!
email.html
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Congratulations!</title>
8 </head>
9 <body>
10 <h2>Congratulations, {{username}}!</h2>
11 <p>Your account has been successfully activated!</p>
12 </body>
13</html>
Modify the send_html()
view to use the templates instead:
1from django.template.loader import get_template
2
3def send_html_template(request):
4 subject, from_email, to = "Hello!", "from@example.com", "huericnan@gmail.com"
5
6 text = get_template('email.txt')
7 html = get_template('email.html')
8
9 username = 'jack'
10
11 d = { 'username': username }
12
13 text_content = text.render(d)
14 html_content = html.render(d)
15
16 email = EmailMultiAlternatives(subject, text_content, from_email, [to])
17 email.attach_alternative(html_content, "text/html")
18 email.send()
19
20 return HttpResponse("HTML email sent.")
Hope this article has been of assistance to you. Thanks for reading!