Recently I came across the challenge of trying to get a Django email form configured and set up to email it on my HostGator Django web host. Below is a tutorial and example of all the details and settings I had to do to get Django to send email via SMTP. Currently my HostGator setup is running Django version 1.4 and Python version 2.7. I am not an expert programmer so there could be another way to do this but I at least wanted to share my settings and setup to send email through SMTP so you had an example. This is a simple contact form example but you can use it for any type of Django form.
If you are not sure what SMTP is, it stands for Simple Mail Transfer Protocol and is the standard framework we use to send mail. SMTP needs to be configured correctly on your email so that your account is not hijacked and used for spam. Additionally, you want to make sure that whenever you have a website that is brining data in from another person that you have checks and balances to ensure that the content being sent to you does not have a virus and is not put in a form that can be used for cross-site scripting or other hacking methods. Basically people can put codes in your form that when submitted to your webserver can cause problems and potentially allow them to get control of it. One of the nice things about Django is that they can stop this if you use their default methods.
Django settings.py File
First we want to talk about the settings.py file and make sure that you have it set up correctly to send email through your HostGator SMTP setting. Now initially I wanted to send the email via SSL but HostGator support said that TLS is another way to encrypt the mail and protect your user account, etc.
Here is the final settings.py code that I had to enable SMTP for HostGator and Django. Note that you will have to put some of your own information in specific parts.
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'secureYOUR-SERVER-NUMBER.hostgator.com'
EMAIL_PORT = '26'
EMAIL_HOST_USER = 'USER@YOURDOMAIN.COM'
EMAIL_HOST_PASSWORD = 'THE-EMAIL-ACCOUNT-PASSWORD'
EMAIL_USE_TLS = True
You need to replace "YOUR-SERVER-NUMBER" with the number of your web server on HostGator. Or if you use another SMTP server like Gmail, or your own Web SMTP server you will need to replace the full EMAIL_HOST with the other server information. Also validate the EMAIL_PORT matches what your email server needs. I set up a special email account to send all my web form emails through so that the password I put isn't compromised with my personal data. Basically this is an account that I set up on my web host that does nothing else but send emails. So replace "USER@YOURDOMAIN.COM" with your SMTP account and "THE-EMAIL-ACCOUNT-PASSWORD" with the password.
Prior to updating my website for real I did some initial testing on my compute using these settings and running a small test Django local SMTP server. I suggest while you finish all the other code below that you keep the settings.py set up to run tests with these configuration entries:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'localhost'
EMAIL_PORT = '1025'
EMAIL_USE_TLS = True
To create a test SMTP server with Django just run this command via the python shell you had set up. It will not send the email buy as you run tests you will be able to see the content of your email display in the shell window.
python -m smtpd -n -c DebuggingServer localhost:1025
Django models.py File
Next I needed to set up my models.py file to contain the right entries to build my form class. Now you could augment this to build some type of database to store these values if you wanted, but I kept it simple and just needed an Email Form Class.
from django.db import models
from django import forms
class EmailForm(forms.Form):
firstname = forms.CharField(max_length=255)
lastname = forms.CharField(max_length=255)
email = forms.EmailField()
subject = forms.CharField(max_length=255)
botcheck = forms.CharField(max_length=5)
message = forms.CharField()
Note that I have one additional field called botcheck which provides a simple way for a human to enter in data that I check against before I send the email. This helps protect from basic spam email bots that don't use captcha type technology. You could make the question anything so that really it needs to be a person that answers it before the email is sent.
Django urls.py File
We need to make sure that the urls.py file has the right URL entries so that the form can be processed correctly. I have three simple URLs - one that is the initial contact form page you see, the next is the url that does the email processing, and last is the thank you url if the form completes correctly. If the form fails, I direct them back to the original form.
If needed you could set up more form validation using AJAX or Javascript and other advanced features to make sure your form was not wiped clean if it failed to process correctly. Since this is a simple email form I was not going to go through all that configuration. Additionally, I did decide to use Django's default form processing routines that does simple validation and other checks to make sure that people do not inject code into my form to try to take over the server, etc.
from django.conf.urls import patterns, url, include
from django.conf import settings
from django.views.generic.base import TemplateView
from views import *
urlpatterns = patterns('',
# Put your site URLs here
# Form URLs
url(r'^email/send/$', sendmail),
url(r'^email/thankyou/$', TemplateView.as_view(template_name='thankyou.html'), name='thankyou'),
url(r'^email/$', TemplateView.as_view(template_name='email.html'), name='email'),
Django views.py File
The data that comes from the HTML form is cleaned to ensure there is no bad HTML or injection attacks. Then it checks the bot check to make sure the answer to my question is provided, which in this case the answer is the word "yes". Then it attempts to send the email via SMTP and using the settings from the settings.py file. Make sure you replace "SENDTOUSER@DOMAIN.COM" with the email account you want to send the mail to.
If for any reason the form is not complete, the botcheck fails, or the SMTP send fails, the code reverts back to the Email URL to displace the form. If it works correctly and sends the email, then it redirects the user to the thank you page. You could replace the redirects with whatever pages you want.
from django.views.generic.base import TemplateView
from django.http import HttpResponseRedirect
from django.core.mail import send_mail, BadHeaderError
from models import EmailForm
def sendmail(request):
if request.method == 'POST':
form = EmailForm(request.POST)
if form.is_valid():
firstname = form.cleaned_data['firstname']
lastname = form.cleaned_data['lastname']
email = form.cleaned_data['email']
subject = form.cleaned_data['subject']
botcheck = form.cleaned_data['botcheck'].lower()
message = form.cleaned_data['message']
if botcheck == 'yes':
try:
fullemail = firstname + " " + lastname + " " + "<" + email + ">"
send_mail(subject, message, fullemail, ['SENDTOUSER@DOMAIN.COM'])
return HttpResponseRedirect('/email/thankyou/')
except:
return HttpResponseRedirect('/email/')
else:
return HttpResponseRedirect('/email/')
else:
return HttpResponseRedirect('/email/')
Django email.html Contact Form Template File
Here is the Django Contact Email Form Template that I use. Make sure to adjust the page where needed to fit your template system. Each section has a class CSS set up that can be configured so that you can format the pages to look however you want. Additionally notice the botcheck area where I ask a simple question. If you want you can change the question to be whatever you want and then in the views.py file just change the answer to match values.
{% extends "base.html" %}
{% block title %}Contact Us{% endblock title %}
{% block content %}
<form method="post" action="/email/send/">{% csrf_token %}
<div class="name">
<label class="label">Name <span class="required">*</span></label>
<span class="span">
<input name= "firstname" class="inputtext" maxlength="255" size="12" />
<label class="spanlabel">First</label>
</span>
<span class="span">
<input name= "lastname" class="inputtext" maxlength="255" size="18" />
<label class="spanlabel">Last</label>
</span>
</div>
<div class="email">
<label class="label">Email Address <span class="required">*</span></label>
<input name="email" class="inputtext" type="text" maxlength="255" size="35" />
</div>
<div class="subject">
<label class="label">Subject <span class="required">*</span></label>
<input name="subject" class="inputtext" type="text" maxlength="255" size="45" />
</div>
<div class="botcheck">
<label class="label">You must answer <u>YES</u> to the question below to<br /> approve sending this email. <span class="required">*</span></label>
Do you want to send me an email? <input name="botcheck" class="inputtext" type="text" maxlength="5" size="5" />
<div class="message">
<label class="label">Message <span class="required">*</span></label>
<textarea name="message" class="inputtextarea" rows="11" cols="45"></textarea>
</div>
<div class="button">
<input class="submitform" type="submit" name="submitform" value="Send Message" />
</div>
</form>
{% endblock content %}
Django thankyou.html Contact Form Thank You Template File
If the contact form submission works then it will direct to this thank you page.
{% extends "base.html" %}
{% block title %}Contact Us - Thank You{% endblock title %}
{% block content %}
<h3>Thank you.</h3>
<p>Your email was sent and I will get back to you as soon as I can.</p>
<p>Return <a href="/">home</a></p>
{% endblock content %}