25- Sending Email with Django

If you have a SMTP server in your organization. First you need to configure your SMTP server to allow your Django server to be able to send email. You can use IIS for example as your SMTP Server and add the IP address of Django Server. In that case you just need to change your settings.py file like this.

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'YOUR_SMTP_SERVER_IPADDRESS'
EMAIL_PORT = 25

 

If you want to use GMAIL SMTP server, your settings.py file needs the following fields. In password field, you can not use your email password, if you try you get authentication errors. On your Gmail Account, Under the "Sign In to Google" section, you need to activate 2 Steps verification first. After 2 Steps verification is activated, you will see an additional option that is called "App Passwords". You need to create an "App Password". That's your 16Digit password.

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = This email address is being protected from spambots. You need JavaScript enabled to view it.'
EMAIL_HOST_PASSWORD = '16DigitPasswordFromGoogle'

 

On your view you simply use following code

from django.core.mail import send_mail
from django.conf import settings

subject = 'Subject Goes Here'
message = 'This is your message body'
email_from = settings.EMAIL_HOST_USER
recipient = This email address is being protected from spambots. You need JavaScript enabled to view it.'
send_mail(subject, message, email_from, [recipient])

 

In my application,I want to inform users when site admin adds a new movie. This works fine but It might be nice if we send an html email instead of a plain text email.

def addmovie(request):
    if request.method=='POST':
        form = AddMovieForm(request.POST, request.FILES)
        if form.is_valid():
            movietitle = form.cleaned_data['title'] # I need cleaned (validated) data the form to be able to work on title. Otherwise Django will say title not found
            form.save()
            messages.success(request, "Movie Added", extra_tags='green')

            users = MyCustomUser.objects.all() #query all users, I will send to email to each one of them
            subject = 'New Movie is Added to our site'
            message = 'Movie Name: ' + movietitle
            email_from = settings.EMAIL_HOST_USER
            for user in users: #users is the list of the users that s returned by the query
                send_mail(subject, message, email_from, [user.email])
        return redirect('addmovie')
    else:
        form = AddMovieForm()
    context = {'form':form}
    return render(request, 'addmovie.html', context)

 

Sending HTML Email:

 To send HTML email, I need to modify views.py a little bit and create a template file (I named the template as email.html). Let's see how we can achieve this.

 views.py

from django.core.mail import send_mail
from django.conf import settings
from django.core import mail
from django.template.loader import render_to_string
from django.utils.html import strip_tags

def addmovie(request):
    if request.method=='POST':
        form = AddMovieForm(request.POST, request.FILES)
        if form.is_valid():
            movieTitle = form.cleaned_data['title'] # I need cleaned (validated) data the form to be able to work on title. Otherwise Django will say title not found
            movieDescription = form.cleaned_data['description'] 
            movieGender = form.cleaned_data['gender'] 
            
            form.save()
            messages.success(request, "Movie Added", extra_tags='green')

            users = MyCustomUser.objects.all() #query all users, I will send to email to each one of them
            subject = 'New Movie is Added to our site'
            #message = 'Movie Name: ' + movietitle
            message = render_to_string('email.html', {'context0': movieTitle, 'context1': movieDescription, 'context2': movieGender,})
            plainMessage = strip_tags(message)
            email_from = settings.EMAIL_HOST_USER
            for user in users: #users is the list of the users that s returned by the query
                mail.send_mail(subject, plainMessage, email_from, [user.email], html_message= message)
        return redirect('addmovie')
    else:
        form = AddMovieForm()
    context = {'form':form}
    return render(request, 'addmovie.html', context)

 

Create a simple html template (email.html)

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body bgcolor="#E03611">
	
    <p>Movie Title: {{ context0 }}</p>
	<p>Movie Description: {{ context1 }}</p>
    <p>Movie Gender: {{ context2 }}</p>
    
    </body>
</html>

 

That's it.