39
Creating The Sign Up Page Part II
Welcome again. We will wrap up the sign up page by continuing from where we left off - that is creating the template. If you haven't checked out the previous part, go ahead and do that.
Alright folks, let's get to it.
As we remember in the last part of the series we set the
template_name
attribute of our RegisterView class to be users/register.html
. So let's go ahead and create an html file inside that directory which is users/templates/users/In Django, when submitting forms we use csrf_token template tag in our html file. CSRF stands for Cross Site Request Forgery. Learn more about this attack from this wikepedia page.
Here in our template we can access the form variable we passed into the context of RegisterView simply by using {{ form }}
. But this will display everything all at once making it look hideous.
To render the form fields manually, we can use
{{ form.name_of_field }}
For example, if we want to render the email field we can say form.email
.Here we have to make sure we take care of any errors and display them nicely to our users.
{% if form.errors %}
<div class="alert alert-danger alert-dismissible" role="alert">
<div id="form_errors">
{% for key, value in form.errors.items %}
<strong>{{ value }}</strong>
{% endfor %}
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
register.html
{% extends "users/base.html" %}
{% block title %} Register Page {% endblock title%}
{% block content %}
<div class="form-content my-3 p-3">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-7">
<div class="card shadow-lg border-0 rounded-lg mt-0 mb-5">
<div class="card-header justify-content-center">
<h3 class="font-weight-light my-4 text-center">Create Account</h3>
</div>
<div class="card-body">
<form method="POST">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-dismissible" role="alert">
<div id="form_errors">
{% for key, value in form.errors.items %}
<strong>{{ value }}</strong>
{% endfor %}
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
<div class="form-row">
<div class="col-md-6">
<div class="form-group">
<label class="small mb-1">First Name</label>
{{ form.first_name }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="small mb-1">Last Name</label>
{{ form.last_name }}
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6">
<div class="form-group">
<label class="small mb-1">Username</label>
{{ form.username }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="small mb-1">Email</label>
{{ form.email }}
</div>
</div>
</div>
<div class="form-row">
<div class="col-md-6">
<div class="form-group">
<label class="small mb-1">Password</label>
{{ form.password1 }}
{{ form.errors.password }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="small mb-1">Confirm Password</label>
{{ form.password2 }}
</div>
</div>
</div>
<div class="form-group mt-4 mb-0">
<button type="submit" class="col-md-12 btn btn-dark">Sign Up</button><br><br>
</div>
</form>
</div>
<div class="card-footer text-center">
<div class="small">
<a href="#">Have an account? Go to Sign in</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
Remember in the last part inside our RegisterView, we created a flash message to be displayed when a user is successfully created. So we need a template to display this message and the best place to put this is in base.html because every other template extends from it.
{% if messages %}
<div class="alert alert-dismissible" role="alert">
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
message.success
in our view, the bootstrap alert will be alert-success
).Oh and there is one more thing to do. Remember in the last part we used an id for the password fields so that we can use a plugin to show/hide password. The best place to put this plugin is inside base.html because we might use it again in other templates.
There are only 2 modifications we need to make.
base.html
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!--Font awesome icons -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
<title>{% block title %} {% endblock %} </title>
</head>
<body>
<div class="container p-3 my-3">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-expand-md navbar-light " style="background-color: #f0f5f5">
<a href="/" class="navbar-brand">Home</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbarCollapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<div class="navbar-nav ml-auto">
<a href="#" class="nav-item nav-link">Profile</a>
<a href="#" class="nav-item nav-link">Logout</a>
<a href="#" class="nav-item nav-link">Sign in</a>
</div>
</div>
</nav>
<!--Any flash messages pop up in any page because this is the base template-->
{% if messages %}
<div class="alert alert-dismissible" role="alert">
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
{% block content %}{% endblock %}
</div>
</div>
</div>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<!-- A plugin for password show/hide -->
<script src="https://unpkg.com/bootstrap-show-password@1.2.1/dist/bootstrap-show-password.min.js"></script>
</body>
</html>
That's it for the sign up page. Now let's see if everything works.
python manage.py createsuperuser
python manage.py runserver
. Thanks for your time. You can find the finished app in github. See you next time with another part of the series.
Any comments and suggestions are welcome.
39