
Hello Techies,
In this blog, we will check how to use Django email confirmation, and Django HTML integration.
In my previous blog, I have covered the basics of Django login and registration features which is Part 1. So you can check that blog also.
Below are the points you are going to learn
- Django HTML Integration
- Django email confirmation
Table of Contents
1. Django HTML Integration
Let’s look at an example of Django HTML integration. So you get an idea of how to integrate Django HTML and add static files to it.
For styling, we need CSS files where we need separate static folders and in this folder, we need sub-folders like CSS, and images that can handle their files independently.
So let’s create a static folder and sub-folders in the account app. I hope you are referring to my previous blog Django login and registration application to check how to do Django HTML Integration and how to add static files in it.

Add style.css in accounts/static/css
/*--reset--*/
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
dl,
dt,
dd,
ol,
nav ul,
nav li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
ol,
ul {
list-style: none;
margin: 0px;
padding: 0px;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
.clearfix {
clear: both;
}
/*--start editing from here--*/
a {
text-decoration: none;
}
.txt-rt {
text-align: right;
}
/* text align right */
.txt-lt {
text-align: left;
}
/* text align left */
.txt-center {
text-align: center;
}
/* text align center */
.float-rt {
float: right;
}
/* float right */
.float-lt {
float: left;
}
/* float left */
.pos-relative {
position: relative;
}
/* Position Relative */
.pos-absolute {
position: absolute;
}
/* Position Absolute */
.vertical-base {
vertical-align: baseline;
}
/* vertical align baseline */
.vertical-top {
vertical-align: top;
}
/* vertical align top */
nav.vertical ul li {
display: block;
}
/* vertical menu */
nav.horizontal ul li {
display: inline-block;
}
/* horizontal menu */
img {
max-width: 100%;
}
/*--end reset--*/
body {
font-family: 'Poppins', sans-serif;
font-size: 100%;
background: url(../images/1.jpg)no-repeat center top;
background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
-ms-background-size: cover;
background-attachment: fixed;
text-align: center;
}
.body_container {
display: -webkit-flex;
display: -webkit-box;
display: -moz-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
justify-content: center;
align-items: center;
-webkit-box-pack: center;
-moz-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
h1 {
font-size: 3.2em;
text-transform: capitalize;
color: #fff;
text-shadow: 1px 1px 1px #000;
letter-spacing: 3px;
margin: .8em 1vw;
text-align: center;
}
.body_container form {
max-width: 500px;
margin: 0 5vw;
border-radius: 8px;
background: transparent;
padding: 3.5vw;
border: solid #fff;
border-width: 5px;
box-sizing: border-box;
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
}
.body_container label {
font-size: 14px;
color: #fff;
float: left;
text-align: left;
margin-bottom: 5px;
text-transform: capitalize;
letter-spacing: 2px;
cursor: pointer;
}
.agile-field-txt {
flex-basis: 100%;
-webkit-flex-basis: 100%;
margin-bottom: 1.5em;
}
.body_container label i {
font-size: 1.1em;
margin-right: 3px;
color: #fd5c63;
}
.body_container input[type="text"],
.body_container input[type="password"] {
width: 100%;
color: #333;
outline: none;
font-size: 15px;
letter-spacing: 1px;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
border: none;
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.49);
-webkit-appearance: none;
background: #fff;
font-family: 'Poppins', sans-serif;
}
.check1 {
text-align: left;
}
label.check {
float: none;
}
.agile_label {
text-align: left;
margin: 10px 0 0;
}
.body_container.w3l-sub {
margin-top: 1em;
flex-basis: 100%;
-webkit-flex-basis: 100%;
}
.body_container input[type=submit] {
width: 100%;
padding: 0.5em 0;
font-size: 1.1em;
letter-spacing: 2px;
cursor: pointer;
border: none;
border-radius: 8px;
border: 2px solid #fd5c63;
background: #fd5c63;
color: #fff;
margin-top:1em;
outline: none;
transition: 0.5s all ease;
-webkit-transition: 0.5s all ease;
-moz-transition: 0.5s all ease;
-o-transition: 0.5s all ease;
-ms-transition: 0.5s all ease;
font-family: 'Poppins', sans-serif;
}
.body_container input[type=submit]:hover {
background: transparent;
border: 2px solid #fff;
color: #fff;
}
.w3ls-bot {
width: 100%;
}
/* switch */
label.switch {
position: relative;
display: inline-block;
height: 23px;
padding-left: 5em;
cursor: pointer;
color: #fff;
}
li:nth-child(2) a,
label.switch {
text-transform: capitalize;
font-size: 14px;
letter-spacing: 2px;
}
.switch input {
display: none;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 22%;
background-color: #999;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 15px;
width: 15px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #fd5c63;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
/* //switch */
.switch-agileits {
width: 100%;
float: left;
}
.form-end {
}
.errorlist{
color:red;
}
/*--responsive--*/
@media(max-width:1920px) {
h1 {
font-size: 3.5vw;
}
}
@media(max-width:1024px) {
h1 {
font-size: 4.5vw;
}
}
@media(max-width:800px) {
h1 {
font-size: 5vw;
}
}
@media(max-width:480px) {
h1 {
font-size: 2.5em;
}
.body_container form {
padding: 7.5vw;
}
.body_container input[type="text"], .body_container input[type="password"] {
padding: 13px 15px;
}
.body_container input[type=submit] {
padding: 0.4em 0;
font-size: 1em;
}
}
@media(max-width:440px) {
h1 {
font-size: 2.3em;
}
.parent {
display: block;
}
}
@media(max-width:320px) {
h1 {
font-size: 1.8em;
}
.body_container form {
padding: 25px 8px;
}
}
/*--//responsive--*/
Use the below image in images folder.

Create the base.html file in accounts/templates/base.html and add the below code in it. These templates help when you want to use the same code or layout in more than one place.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Django Simple Login{% endblock %}</title>
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}"/>
</head>
<body>
<header>
<h1>Django Registration and Login</h1>
{% if user.is_authenticated %}
Welcome {{ user.username }}!
<a href="{% url 'logout' %}">logout</a>
{% else %}
<a href="{% url 'login' %}" style="font-size: 25px;font-weight: 600;color:#bca0ff">login</a>
<a href="{% url 'sign_up' %}" style="font-size: 25px;font-weight: 600;color:#bca0ff">Create New Account</a>
{% endif %}
</header>
<hr>
<main>
{% block content %}
{% endblock %}
</main>
<hr>
<footer>
<a href="http://techpluslifestyle.com">techpluslifestyle.com</a>
</footer>
</body>
</html>
As you can see in the above code where multiple tags we used like {% block title %} tag will replace with html title tag , {% load static %}, this tag tells the template engine to use the files in the static folder in this template and using the {% static ‘static_filename’ %} we can add the multiple static files in our template, {% block content %} tag use for page content.
Create the home.html file in accounts/templates/home.html and add the below code in it.
{% extends 'base.html' %}
{% block title %}Login{% endblock %}
{% block content %}
<div style="font-size: 15px;font-weight: 300;color:white">
<p>Welcome to Tech Plus Lifestyle blogs. </p>
</div>
{% endblock %}

Html code for Login.html
{% extends 'base.html' %}
{% block content %}
<div class="body_container box box--big">
<!-- form starts here -->
<form id="login-form" method="post" action="#">
{% csrf_token %}
<div class="agile-field-txt">
<label>
<i class="fa fa-user" aria-hidden="true"></i> username </label>
<input id="id_username" name="username" placeholder="Enter your name " required=""
type="text" class="form-control">
</div>
<div class="agile-field-txt">
<label>
<i class="fa fa-envelope" aria-hidden="true"></i> password </label>
<input name="password" type="password" class="form-control"
placeholder="Enter your password " required="" id="myInput id_password" >
</div>
{% if form.errors %}
<p class=" label label-danger" style="color:red">
Your username and password didn't match.
Please try again.
</p>
{% endif %}
<div class="w3ls-bot">
<div class="form-end">
<input type="submit" value="LOGIN">
</div>
<div class="clearfix"></div>
<br/>
<div class="form-end">
<a href="{% url 'sign_up' %}" style="background-color: #555555;padding: 15px 32px;display: inline-block;
color:white;margin: 4px 2px;">Create New Account</a>
</div>
</div>
</form>
</div>
{% endblock %}

2. Django Email Confirmation
Let’s see how to create sign-up functionality with email confirmation. Using this functionality the user will not be able to access the login account without email confirmation.
Add url in account/urls.py file
from django.contrib import admin
from django.urls import path
from django.contrib.auth import views as auth_views
from django.contrib.auth.forms import UserCreationForm
from . import views
urlpatterns = [
path('sign_up/', views.sign_up, name="sign_up"),
path('activate/<uidb64>/<token>', views.activate, name='activate'),
path('login', auth_views.LoginView.as_view(),{'template_name': 'registration/login.html'}, name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
Add below code into accounts/models.py file
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
# other fields...
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
Add the below code in setting.py file for email configuration.
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL = '[email protected]' # here provide your gmail email id
SERVER_EMAIL = '[email protected]' # here provide your gmail email id
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com' # here provide your gmail email id
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'example' # gmail password
EMAIL_PORT = 587
Now add the sign_up function in account/views.py file
from django.contrib.auth import login
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from django.core.mail import EmailMessage
from django.http import HttpResponse
from .token import account_activation_token
from .forms import SignUpForm
def sign_up(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user_obj = form.save(commit=False)
user_obj.is_active = False
user_obj.save()
current_site = get_current_site(request)
subject = 'Activate Your Account'
message = render_to_string('account_activation_email.html', {
'user': user_obj,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user_obj.pk)),
'token': account_activation_token.make_token(user_obj),
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(subject, message, to=[to_email], from_email='[email protected]')
email.send()
return HttpResponse('We have sent you an email, please confirm your email address to complete registration')
else:
form = SignUpForm()
return render(request, 'sign_up.html', {'form': form})
Create the forms.py file in accounts folder and add the below code in accounts/forms.py file.
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class SignUpForm(UserCreationForm):
email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2', )
HTML Code For Sign Up Page
{% extends 'base.html' %}
{% block content %}
<div class="body_container box box--big">
<!-- form starts here -->
<form id="sign-up-form" method="post" action="#">
{% csrf_token %}
<div class="agile-field-txt">
<label> Username </label>
<input id="id_username" name="username" placeholder="Enter your name " required=""
type="text" class="form-control">
</div>
<div class="agile-field-txt">
<label> Email </label>
<input id="id_email" name="email" placeholder="Enter your email " required=""
type="text" class="form-control">
</div>
<div class="agile-field-txt">
<label> password </label>
<input name="password1" type="password" class="form-control"
placeholder="Enter your password " required="" id="id_password" >
</div>
<div class="agile-field-txt">
<label>confirm password </label>
<input name="password2" type="password" class="form-control"
placeholder="Enter your confirm password" required="" id="id_password" >
</div>
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<p style="color: white">{{ error }}</p>
{% endfor %}
{% endfor %}
{% endif %}
<div class="w3ls-bot">
<div class="form-end">
<input type="submit" value="Create">
</div>
<div class="clearfix"></div>
<br/>
<div class="form-end">
<a style="background-color: #555555;padding: 15px 32px;display: inline-block;
color:white;margin: 4px 2px;" href="{% url 'login' %}">Login</a>
</div>
</div>
</form>
</div>
{% endblock %}

Let’s write the code for token for this function we will create one separate file in accounts folder. So create token.py file in accounts folder and add below code.
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from six import text_type
class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
text_type(user.pk) + text_type(timestamp) +
text_type(user.profile.email_confirmed)
)
account_activation_token = AccountActivationTokenGenerator()
Email sign-up functionality is now complete. We will now develop a feature for email activation clicks. So now first add URL in account/urls.py file.
path('activate/<uidb64>/<token>', views.activate, name='activate'),
Add below code for activate function in accounts/views.py file.
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from .token import account_activation_token
def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except Exception as e:
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.profile.email_confirmed = True
user.save()
login(request, user)
return redirect('home')
else:
return render(request, 'account_activation_invalid.html')</code></pre></amp-fit-text>
Create the Template for the Account activation in the accounts/template folder and add the below code in it.
{% autoescape off %}
Hi {{ user.username }},
Please click on the link below to confirm your registration:
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
{% endautoescape %}

Let’s check Django-registration send activation email which I received.

So this is one example of send email validation in Django.
If you’re experiencing email issues, such as unable to receive any mail after you sign up, use Google’s less secure app option and enable that option. Check the below image for the same.

I hope you understand every step of How to create a Django HTML Integration and Django email confirmation. If you still have any query do comment below.
Refer a below GitHub link for source code(Django HTML Integration and Django email confirmation).
https://github.com/pranalikambli/login_registration_with_django_extra_features
