Creating a contact form using SendGrid with Django
This article will guide you through building a simple contact form using Django and SendGrid.
When running a web service or a blog, implementing a mail delivery system is often necessary. However, building such a system is not easy, and many difficulties are involved in creating one on your own.
I once built and operated a service that combined Django and Gmail to deliver emails. However, even though I believed the settings were done correctly, emails were not delivered as expected on many occasions. This is where SendGrid comes in. As a cloud-based email delivery system, it is easy to set up, and in my experience, email delivery problems rarely occur when using SendGrid.
Furthermore, SendGrid is very easy to integrate with your existing web application. It is currently one of the most popular email delivery systems among web developers.
In this article, I will show you how to use SendGrid in Django to easily send emails through a contact form.
About SendGrid's Free Tier
SendGrid offers both free and paid plans. The free plan is limited to sending 100 emails per day. While the free and paid plans may have some additional restrictions beyond the difference in the number of email distributions, I have found the free plan to be sufficient for managing my website without any significant issues.
Two Ways to Integrate SendGrid into Django
There are two ways to integrate SendGrid into Django: using an SMTP server or the Web API. Most tutorials on using Django+SendGrid found online demonstrate the SMTP solution. However, the Web API is also a viable option.
In this document, I will describe how to use the Web API. For reference, a simple explanation of the SMTP solution can be found in the official documentation.
Environment for APP development
Integrate SendGrid on top of Django's basic setup. If you are using Django for the setup, please refer to this article.
Application Overview
We will create an application that generates a simple form and sends an email to the site owner when the form is submitted with valid input.
To confirm the implementation of SendGrid, we will only create the Form, Template, and corresponding View for this simple application. We will not create a Model.
We will use the following package to forward mail via web API.
Project file structure
The project is named django_08
, and the app is named "send_test".
When using SendGrid, an API key is required. This key should be written in the .env file, which will be described later.
Implementation Process
The process might involve some back and forth, but generally, it follows these steps:
1. Setting up SendGrid
To start, go to the SendGrid website and obtain an API key.
The process of obtaining an API key has been covered in various tutorials, so I'll just show you a screenshot of the page to get it in this blog. It can be found in the settings at the bottom of the sidebar navigation.
2. Installing the Package
Please install the packages listed in the accompanying list, assuming that the basic package for running Django and Django itself have already been installed.
django-environ
django-sendgrid-v5
3. settings.py
Add the following code to use the web API in a local environment.
If you set SENDGRID_SANDBOX_MODE_IN_DEBUG
to False
, the email will actually be sent to a specified email address instead of being sent to the console. I like this method because it feels more practical.
EMAIL_BACKEND = "sendgrid_backend.SendgridBackend"
SENDGRID_API_KEY = os.getenv('SENDGRID_API_KEY')
SENDGRID_SANDBOX_MODE_IN_DEBUG=False
Additionally, create an .env
file and enter the value of the SendGrid API_KEY.
SENDGRID_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
4. urls.py
Create two files: urls.py
in the Django root directory and urls.py
in the application folder.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('send_test.urls', namespace='send_app')),
]
from django.urls import path
from send_test import views
app_name = 'send_app'
urlpatterns = [
path('', views.home, name='send_test'),
]
Only include very basic content in the view. Write the code as shown below.
from django.shortcuts import render
def home(request):
return render(request, 'send_test/home.html')
5. forms.py
Create a form using the accompanying code.
from django import forms
class SendForm(forms.Form):
email = forms.EmailField(label="Email", max_length=100)
content = forms.CharField(label="Content", max_length=200)
6. Templates
Next, we have the template file.
Please refer to the previous file structure.
We have created a folder with the application's name in the templates folder and placed home.html
in it.
As you can see, each file contains fundamental code.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends 'base.html' %}
{% block content %}
<h1>SendGrid Test App</h1>
<form id="TestForm" method="post" action="{% url 'send_app:send_test' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" value="Test">send message</button>
</form>
{% endblock %}
http://127.0.0.1:8000/
(the URL and port may differ depending on the environment). When you access it, the accompanying image will be displayed:
7. views.py
This section is the most important in this tutorial.
Below the try
block in this view, there is a function called send_mail
that sends an email using SendGrid after validating the submitted data. This single line of code is all that is needed to send an email.
Regarding the send_mail
function, please note that the fourth argument is used to specify the email address of the recipient.
To avoid writing the email address directly in the code, you can assign it to an environment variable instead.
import os
from django.http import HttpResponse
from django.shortcuts import render
from .forms import SendForm
from django.core.mail import send_mail, BadHeaderError
def home(request):
if request.method == "POST":
form = SendForm(request.POST)
if form.is_valid():
subject = 'Message from TestAccount'
message = form.cleaned_data['content']
sender = form.cleaned_data['email']
recipients = os.getenv('TO_EMAIL')
try:
send_mail(subject, message, sender, [recipients], fail_silently=False)
form = SendForm()
return HttpResponse('Successfully sent a message!')
except BadHeaderError:
return HttpResponse('Error!')
form = SendForm()
return render(request, 'send_test/home.html', {'form':form })
That's all! With SendGrid, you can create a reliable email delivery environment with a simple setup and code, as shown above. There's no reason not to use it, so let's all start using it actively. Happy coding!