Let’s build a simple contact form for our Django website. We can take advantage of Django’s built-in email support to make this relatively painless.

Complete working code can for this tutorial can be found on Github.

Initial setup

First let’s create our virtual environment and install Django:

mkvirtualenv django-contact-form
pip install django

Next let’s create a new Django project called django-contact-form and then an app within it called send_email:

django-admin startproject django_contact_form
cd django_contact_form
python manage.py startapp send_email

To make sure everything installed correctly let’s migrate and then runserver. If you open you browser to 127.0.0.1:8000 you should see the lovely pastel blue “Welcome to Django” screen:

python manage.py migrate
python manage.py runserver

Update settings.py

We’ve added an app to our Django project, so we need to add send_email to the top of the INSTALLED_APPS section:

# django_contact_form/settings.py
...
INSTALLED_APPS [
    'send_email',
    ...
]

And at the bottom of your settings.py file (though really you can place this anywhere) add a line specifying which email backend we’ll use:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

For now we’ll be outputting our email to the console. Later we can add a few lines to this settings.py file to specify whatever production backend mail server–MailGun, SendGrid, etc–we’d like.

Update urls.py

Since we’ve added an app to our Django project we need to update the root urls.py file, adding include to the top line and a new urlpattern for the app:

# urls.py
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('send_email.urls')),
]

Next create a new file, send_email/urls.py, and add the following code:

# send_email/urls.py
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^email/$', views.email, name='email'),
    url(r'^success/$', views.success, name='success'),
]

Create forms.py

Still within our send_email app create a new file, forms.py, which will contain the forms in our actual contact form:

# send_email/forms.py
from django import forms


class ContactForm(forms.Form):
    from_email = forms.EmailField(required=True)
    subject = forms.CharField(required=True)
    message = forms.CharField(widget=forms.Textarea, required=True)

We’re using Django’s built-in Forms API here to quickly create three fields.

Create views.py

Let’s create the view now that will do the bulk of the work for our contact form. Update the existing send_email/views.py file:

# send_email/views.py
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm


def email(request):
    if request.method == 'GET':
        form = ContactForm()
    else:
        form = ContactForm(request.POST)
        if form.is_valid():
            subject = form.cleaned_data['subject']
            from_email = form.cleaned_data['from_email']
            message = form.cleaned_data['message']
            try:
                send_mail(subject, message, from_email, ['[email protected]'])
            except BadHeaderError:
                return HttpResponse('Invalid header found.')
            return redirect('success')
    return render(request, "email.html", {'form': form})


def success(request):
    return HttpResponse('Success! Thank you for your message.')

There’s a lot going on here! We start by importing send_email and BadHeaderError for security reasons. At the bottom of the imports we reference ContactForm which we just created in our forms.py file.

Create templates

Final step! We need to create the templates for our email and success pages. Within send_email create a new templates directory and add new files for email.html and success.html:

# send_email/templates/email.html
<h1>Contact Us</h1>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <div class="form-actions">
      <button type="submit">Send</button>
    </div>
</form>
# send_email/templates/success.html
<h1>Success! Email sent.</h1>

Send first email

Load http://127.0.0.1:8000/email/ in your web browser, fill out the form, and click the Send button.

You will be redirected to the http://127.0.0.1:8000/success/ if the email goes through.

And in your console you can see that the email was sent:

Next Steps

Check out Django for Beginners, a free online book on how to create and deploy multiple Django applications. Starting with a simple “Hello, World” application it progresses through multiple web applications of increasing complexity showing Django best practices along the way.