Building Contact Us Page

In this lesson, we are going to create a Contact Us page. This page will allow our readers to send feedback directly to the admin email address.

Open models.py from the blog app and append the Feedback Model class to the end of the file as follows:

TGDB/django_project/blog/models.py

To commit the changes run makemigration followed by migrate command.

Open blog’s urls.py file and add the following URL pattern towards the beginning of the urlpatterns list:

TGDB/django_project/blog/urls.py

Now create a FeedbackForm class in the blog’s forms.py as follows:

TGDB/django_project/blog/forms.py

Next, create a view function called feedback() at the end of the blog app’s views.py file as follows:

TGDB/django_project/blog/views.py

This view shows feedback form and saves the submitted feedback to the database

Next, we need a template to show the Contact Form. Create a new template called feedback.html inside the blog app i.e blog/templates/blog with the following code:

TGDB/django_project/blog/templates/blog/feedback.html

To view our creation visit http://127.0.0.1:8000/feedback/ and try submitting a feedback or two.

Adding Feedback Model to Django Admin

Open blog’s admin.py file and add FeedbackAdmin class to the file as follows:

TGDB/django_project/blog/admin.py

Visit Feedback list page (http://127.0.0.1:8000/admin/blog/feedback/) in the Django Admin and you should get a page like this:

Sending Emails

Now our site has the ability to accept feedback from the user and site admins can view them using Django Admin. We also want to inform the site admins whenever a new feedback is submitted. To do that, we have to learn how to send email in Django.

Before sending emails in Django, we have to set some variables in the settings.py. Open settings.py and add the following variables towards the end of the file:

TGDB/django_project/django_project/settings.py

Here is a rundown of each variable we have set:

SERVER_EMAIL: It specifies the email address which Django will use to send error messages to ADMINS and MANAGERS.

EMAIL_BACKEND: It specifies the name of the backend to use for sending emails. The 'django.core.mail.backends.smtp.EmailBackend' means that Django will use SMTP Server to send emails. Django has many other backends. Here are other two commonly used backends:

  1. django.core.mail.backends.filebased.EmailBackend
  2. django.core.mail.backends.console.EmailBackend

The former allows us to write the email to a file instead of forwarding it to an SMTP server. And the latter prints the email directly to the console.

EMAIL_HOST: It specifies the address of the Email Server or SMTP Server. In this case, we are using Gmail SMTP Server i.e smtp.gmail.com.

EMAIL_HOST_USER: It specifies the username of the SMTP Server specified in EMAIL_HOST.

EMAIL_HOST_PASSWORD: Password of the SMTP server specified in the EMAIL_HOST.

EMAIL_PORT: Port to use to connect to the SMTP server.

EMAIL_USE_TLS: It specifies whether to use TLS secure or not.

DEFAULT_FROM_EMAIL: It specifies the default email address to use for ordinary correspondence from the site managers. In our case SERVER_EMAIL, EMAIL_HOST_USER and DEFAULT_FROM_EMAIL is same, so Django will use "infooveriq@gmail.com" for ordinary correspondence as well as for reporting errors.

ADMINS: It specifies a list of people to send error notifications. When the site is in production (i.e DEBUG = False) and views raises an exception then Django will send an email to all the to all the people specified in the ADMINS list. Each item in ADMINS list is a tuple. For example:

MANAGERS: It specifies a list of people to send broken link emails for 404 NOT FOUND errors. It accepts emails in the same format as ADMINS.

To enable this feature you have add 'django.middleware.common.BrokenLinkEmailsMiddleware' middleware in the MIDDLEWARE setting in settings.py. To do so, open settings.py file and append 'django.middleware.common.BrokenLinkEmailsMiddleware' middleware to the MIDDLEWARE list as follows:

TGDB/django_project/django_project/settings.py

Remember that Django will automatically send emails to people listed in ADMINS and MANAGERS only in production (i.e DEBUG=False). That’s why, we won’t be able to fully test these functionalities until we deploy our site, which we will do in Deploying Django Project lesson.

Testing email using sendtestemail

Django provides a sendtestemail command which sends a test email to the specified email id. This command is commonly used to test whether everything is working as expected or not. It uses email id specified in DEFAULT_FROM_EMAIL setting to send the email.

In the command prompt or terminal enter the following command:

The above command would send an email to testmail@example.com from infooveriq@gmail.com. You should replace testmail@example.com with the email where you want to send the test mail.

On my machine, When I tried to run the above command, I got the following error:

Notice the error in the fourth line of the output i.e smtplib.SMTPAuthenticationError. This is a common problem when you try to send email from a Gmail account. This error may occur due to the following reasons:

  1. You have entered wrong username/password in settings.py file.
  2. 2-factor authentication is enabled on your account.
  3. “Allow less secure apps” setting is turned off.

First off, make sure you have entered correct username and password in settings.py file. Next, check whether you have enabled 2-factor authentication on your Gmail account by visiting https://myaccount.google.com/security. If so, disable it. At last, check whether you have “Allow less secure apps” setting turned off by visiting https://myaccount.google.com/security . If so, turn it on. In my case, the culprit was “Allow less secure apps”.

After doing these steps you should be able to send a test mail using the sendtestemail command.

If sendtestemail succeeds in sending the email, you should get a response like this:

Instead of sending email to the specified id, you can also use sendtestemail to send email to ADMINS or MANAGERS by using the following command:

As the situation stands, our feedback() view just saves the submitted feedback into the database, it doesn’t send any email to the site ADMINS or MANAGERS. In the next section, we are going to change this.

The mail_admins() function

The main_admins() function sends the email to the site admins i.e list of emails specified in the ADMINS list in settings.py. It’s syntax is:

Syntax:

Subject: The subject of the email.

message: The message.

fail_silently: On error mail_admins() raises gaierror (gai stands for getaddrinfo()) which translates to 500 Internal Server Error on production. If for some reason you want to ignore errors silently set this parameter to True.

The mail_admins() uses SERVER_EMAIL setting as sender’s email.

Let’s modify feedback() view function in blog’s views.py to use mail_admins() function as follows:

TGDB/django_project/blog/views.py

Visit feedback page at http://127.0.0.1:8000/feedback/, fill out the form and hit Submit.

In addition to saving the feedback to the database this time feedback() view will send an email to the site admins informing them about the submitted feedback. This is how email will like:

On the other hand, if main_admins() encounters an error while sending emails then it will throw gaierror exception like this:

In the production, users will get a generic 500 Internal Server Error page.

Note: To checkout this version of the repository type git checkout 22a.

Leave a Comment