In this blog tutorial, we will show you the step by step guide of implementing the above-mentioned features in your web app. This is a long blog so to make it easy for you to understand, we have divided the blog in the following section:
- Create a Registration Form
- Create a Login Form
- Display Logged in User’s info in Navigation Bar
- Perform Logout
- Control routing
- User should be redirected to the login page when we browse the app for the first time
- If a user is already logged in then s/he should be redirected to the dashboard while browsing the login and signup pages
- Only logged in user should be allowed to access other methods defined in your Django views
How to Create a Registration Form in Django?
In this section first we will create a Registration form. We will first create an HTML Template. So in your template folder create a file register.html. Add a simple form like shown below:
<h3>Register</h3>
<form method="POST" action=">
{% csrf_token %}
{{form}}
<input type="submit" name="Create User">
</form>
In your views create a view for registration as below:
from django.contrib.auth.forms import UserCreationForm
def registerPage(request):
form = UserCreationForm()
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
context = {'form':form}
return render(request, 'account/register.html, context)
In your URLs add a URL for registration. Since it is a one time job add routed for login, logout and register here only:
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.registerPage, name="register"),
path('login/', views.loginPage, name="login"),
path('logout/', views.logoutUser, name="logout"),
path('', views.home, name="home"),
]
Above URL patterns mean that I have three routes register, login, and logout which performs the actions mentioned in registerPage, loginPage and logoutUser of views.py respectively. Also when the path is empty it follows the default view mentioned in-home method of views.
Save this and run your server: python manage.py runserver
You should see the output like below:
This is the default form provided by Django’s Authentication module. This module is very useful since we needn’t take care of any security concerns. We just need to learn how to use the properties available in this package.
Register a new user and click submit. Since we haven’t done the page redirection, you will not see any action happening after clicking the submit button. But the user is created successfully. To check that go to your django admin http://127.0.0.1:8000/admin. Click users and you will find your newly created user there
How to Create a Custom Registration Form in Django using inbuilt Django Authentication?
By default, the registration form provided by the Django authentication package displays the username, first password, and second password which is a confirmation password. But as our business requirement increases we want to add fields such as firstname, lastname, email, etc.
Inorder to create a custom form in Django using Django Authentication method create a new file with name forms.py and add the following code:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
We did the import of UserCreationForm to create form utilizing the property given by Django. We did the import of User because this has the model defined for users of our web app.
In the fields section we added four fields for now. But based upon our business requirement we can add or remove them.
We created a class that creates a custom form. Now we need to import that in our registerPage view like shown below:
from django.contrib.auth.forms import UserCreationForm
from .forms import CreateUserForm
def registerPage(request):
form = CreateUserForm()
# form = UserCreationForm()
if request.method == 'POST':
if form.is_valid():
form.save()
return redirect('login')
context = {'form':form}
return render(request, 'account/register.html, context)
Now what we did is that we used CreateUserForm instead of default UserCreationForm. This allowed us to introduce new fields in the registration field. We also added return redirect(‘login’). If the form registration is completed it will redirect you to the login page.
Now that we have used the custom Form we can generate the fields in register.html page like shown below:
<h3>Register</h3>
<form method="POST" action=">
{% csrf_token %}
{% for field in form %}
{{field.label}}
{{field}}
<br>
{{form.as_p}}
{% endfor %}
<input type="submit" name="Create User">
</form>
How to Create a Login Form in Django?
In views import authenticate, login and logout and create a new method loginPage as shown below:
from django.contrib.auth import authenticate, login, logout
def loginPage(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect("home")
context = {}
return render(request, 'account/login.html', context)
With this code whenever we browse the URL /login views.loginPage, this method is called. What this method does is it checks it the method is POST method. If that is true that it gets username and password from the post method and uses Dnajgo’s Authentication method to compare the entered username and password with the one that is stored in database. Than if the request is successful it returns to home page.
Create a Login Template
We need to create a template to reflect the Login Interface. So you can either use a normal form or the one mentioned below:
<h3 id="form-title">LOGIN</h3>
</div>
<div class="d-flex justify-content-center form_container">
<form method="POST" action="">
{% csrf_token %}
<div class="input-group mb-3">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-user"></i></span>
</div>
<input type="text" name="username" placeholder="Username..." class="form-control">
</div>
<div class="input-group mb-2">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="password" name="password" placeholder="Password..." class="form-control" >
</div>
<div class="d-flex justify-content-center mt-3 login_container">
<input class="btn login_btn" type="submit" value="Login">
</div>
</form>
</div>
Whichever form you will use, take a note of the following things:
- Add {% csrf_token %} after the first line you create a form
- The name for username and password which we have used in the views should match with that of template.
- The Form we build here is a POST method form and it sends username and password to the view.
How to display logged in User’s name in your dashboard?
Now that we have created login and register pages and they are working properly, we will now display the user who is logged in at the moment. This is an easy task because as the login session has started with the inbuilt authentication we can now see the user who requested the login.
To get the logged in User’s username in any location of your dashboard add the following code:
<span>User: {{ request.user }}</span>
This displays the username and you can add it in the navigation bar or any location in your dashboard. With this, we are done with the major implementation of the login and registration. Next we will perform a logout:
How to add logout in Django Application?
Adding a logout is quite easy because we have an inbuilt property provided by the Django authentication package. We just need to pass our request to the logout function. The code below shows the necessary imports and the logout method. We do not need any logout page but we need to create a route in the urls.py. Please find that route top in the Creating URL section.
from django.contrib.auth import authenticate, login, logout
def logoutUser(request):
logout(request)
return redirect('login')
How to redirect to the Login Page when user browser the app for the first time
If you are following our blog from the very beginning than even after implementing the login logout, you can still browse our app from the url. This is because we haven’t set any restriction that says redirection to the login page if not logged in. Authentication is yet to be checked. Therefore I will be showing you a partial implementation of checking authentication in one method. You can than continue it in your desired methods.
The solution is quite simple you need to import the following decorator from django authentication:
from django.contrib.auth.decorators import login_required
login_required decorator when implemented makes sure that whenever a method is called the login is done and a session has been active. If login is not done it redirects to a route that we mention in the code.
So except the login, logout and register methods add the following code ontop of every methods like shown below:
@login_required(login_url='login')
The above decorator redirects to the login url. This decorator should be used like shown below:
@login_required(login_url='login')
def home(request):
@login_required(login_url='login')
def customers(requsets):
@login_required(login_url='login')
def products(request)
How to redirect logged-in users to dashboard when they browse login and register pages in the Django web app?
If a user is not logged in and tries to browse our application we made the arrangements which makes sure that the user performs the login first. But what if the logged in user tries to browse the login and signup pages? We have solution for that problem as well.
Django is really a problem solver. Because due to the inbuilt packages provided by Django we do not need to do extra coding. In the Login and Register method, we need to check if the page is authenticated or not. If the page is authenticated then redirection to the home page is to be done. If not authenticated, which means a user needs to either login or register. To modify your register and login code like below:
from django.contrib.auth import authenticate, login, logout
def registerPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
user = form.cleaned_data.get('username')
context = {'form': form}
return render(request, 'account/register.html', context)
def loginPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect("home")
context = {}
return render(request, 'account/login.html', context)