User authentication is a critical aspect of web applications, and ensuring the security of user accounts is paramount. In this tutorial, we’ll explore how to implement password change and password reset (forgot password) functionality in a Django application. These features allow users to update their passwords and recover their accounts in case they forget their passwords.
Table of contents
Prerequisites
Before we proceed, ensure that you have a Django project with user authentication set up. If not, you can follow the steps in the previous tutorial on creating signup, login, and logout functionality in Django.
Password Update Change Functionality
Lets create view, templates and urls for Password Update
Step 1: Create a Password Change View
In your app’s views.py
file, create a view for password change:
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth import update_session_auth_hash
from django.shortcuts import render, redirect
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # To keep the user logged in
return redirect('password_change_done')
else:
form = PasswordChangeForm(request.user)
return render(request, 'change-password/change_password.html', {'form': form})
def password_change_done(request):
return render(request, 'change-password/password_change_done.html')
Step 2: Create a Password Change Template
Create a folder named
in your app’s templates directory. Inside this folder, create a file named change-password
change-password/change_password.html
. This is where you can customize your password change form:
{% extends "base.html" %}
{% block title %}Change Password{% endblock %}
{% block content %}
<h2>Change Password</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Change Password</button>
</form>
{% endblock %}
Step 3: Define URL for Password Change
In your app’s urls.py
file, define the URL for the password change view:
from django.urls import path
from . import views
urlpatterns = [
# ... (other URLs)
path('change_password/', views.change_password, name='change_password'),
path('password_change_done/', views.password_change_done, name='password_change_done'),
]
Step 4: Create a Password Change Done Template (Optional)
Optionally, you can create a template for the password change success page: change-password/change_password.html
{% extends "base.html" %}
{% block title %}Password Changed{% endblock %}
{% block content %}
<h2>Password Changed</h2>
<p>Your password has been successfully changed.</p>
{% endblock %}
Forgot Password (Password Reset) Functionality
Lets create view, templates and Urls for Password Forgot
Step 1: Create a Password Reset View
Django provides built-in views and templates for password reset functionality, so you don’t need to create a custom view for this. However, you should set up the necessary templates.
Step 2: Create Password Reset Templates (Optional)
You can customize the password reset templates if needed. Create the following templates in your app’s templates/password-reset
directory:
password_reset_form.html
: Customize the password reset form.
{% extends "base.html" %}
{% block title %}Password Reset{% endblock %}
{% block content %}
<h2>Password Reset</h2>
<p>Enter your email address to reset your password.</p>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Reset Password</button>
</form>
{% endblock %}
password_reset_subject.txt
: Customize the subject of the password reset email.
Password Reset for Your Website
password_reset_email.html
: Customize the content of the password reset email.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Password Reset</title>
</head>
<body>
<p>Click the following link to reset your password:</p>
<p><a href="http://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}">Reset Password</a></p>
<p>If you didn't request a password reset, please ignore this email.</p>
</body>
</html>
password_reset_done.html
: Customize the confirmation page after a password reset email is sent.
{% extends "base.html" %}
{% block title %}Password Reset Email Sent{% endblock %}
{% block content %}
<h2>Password Reset Email Sent</h2>
<p>We've sent you an email with instructions on how to reset your password. Please check your inbox.</p>
{% endblock %}
password_reset_confirm.html
: Customize the password reset confirmation page.
{% extends "base.html" %}
{% block title %}Reset Password{% endblock %}
{% block content %}
<h2>Reset Password</h2>
<p>Enter your new password below:</p>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Reset Password</button>
</form>
{% endblock %}
You can find the default templates in Django’s source code and modify them according to your project’s design.
Step 3: Define URLs for Password Reset
In your app’s urls.py
file, include the built-in password reset URLs
from django.contrib.auth import views as auth_views
from django.urls import path
urlpatterns = [
# ... (other URLs)
path('password_reset/', auth_views.PasswordResetView.as_view(
template_name='password-reset/password_reset_form.html',
email_template_name='password-reset/password_reset_email.html',
subject_template_name='password-reset/password_reset_subject.txt',
success_url='/password_reset_done/'
), name='password_reset'),
path('password_reset_done/', auth_views.PasswordResetDoneView.as_view(
template_name='password-reset/password_reset_done.html'
), name='password_reset_done'),
path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(
template_name='password-reset/password_reset_confirm.html',
success_url='/password_reset_complete/'
), name='password_reset_confirm'),
path('password_reset_complete/', auth_views.PasswordResetCompleteView.as_view(
template_name='password-reset/password_reset_complete.html'
), name='password_reset_complete'),
]
Step 3: Configure Email Settings
As we are going to send email on for reset password, we need to setup configuration in settings.py
. Open your project’s settings.py
file and configure your email settings. For this example, we will use Gmail’s SMTP server for sending emails:
# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'your_email_password'
Replace [email protected]
and your_email_password
with your Gmail email and password.
Note that using your actual email and password directly in your code is not recommended for production. Instead, consider using environment variables or other secure methods to store these credentials. Read more on How to Protect Sensitive Data in Python Projects like Django and Flask
Finalizing Setup and Run Server
Here is the updated base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Your Website Title{% endblock %}</title>
<!-- Add your CSS and JavaScript links here -->
</head>
<body>
<header>
{% if user.is_authenticated %}
<p>Hello, {{ user.username }}! | <a href="{% url 'change_password' %}">Change Password</a> | <a href="{% url 'logout' %}">Logout</a></p>
{% else %}
<p><a href="{% url 'login' %}">Login</a> | <a href="{% url 'signup' %}">Sign up</a> | <a href="{% url 'password_reset' %}">Reset Password</a></p>
{% endif %}
</header>
<main>
{% block content %}
{% endblock %}
</main>
<footer>
<!-- Add your footer content here -->
</footer>
</body>
</html>
Finally, start the development server:
python manage.py runserver
You can now access your application at http://localhost:8000/
and navigate to the registration page to sign up, and subsequently, you can add login and logout functionality as needed.
Conslusion
With these steps, you’ve implemented password change and password reset (forgot password) functionality in your Django application. Users can now update their passwords and recover their accounts if they forget their passwords. Customization options are available for the templates and views to match your project’s requirements and design.
Find this project on Github.
Blogs You Might Like to Read!
- Folder and Directory Structure for Django Project: Best Practices
- Django Best Practices for Building Robust Web Applications
- How To Send Email in Django and DRF
- How to use Login Required in Django: Restrict View Access
- Django User Registration with Email Confirmation
- How to Create RBAC in Django with Multiple Users Types