How to Implement Reset Password Functionality in a Django Application
Password reset is an essential feature for any application that has user authentication. Fortunately, Django provides a powerful and secure built-in system to handle this entire workflow — from requesting a password reset to setting a new one via an email link.
In this article, you'll learn how to implement the forgot/reset password flow in a Django application using Django’s auth system.
Prerequisites
- Has the authentication system enabled (
django.contrib.auth) - Uses Django’s built-in
Usermodel or a custom user model - Optional Knowledge on sending email from django server (we’ll start with console backend for dev)
The Reset Password Flow in Django
Django offers four views to handle the reset password process:
| Step | View | Template | Purpose |
|---|---|---|---|
| 1 | PasswordResetView |
password_reset.html |
User submits email |
| 2 | PasswordResetDoneView |
password_reset_done.html |
Confirmation that email is sent |
| 3 | PasswordResetConfirmView |
password_reset_confirm.html |
User sets new password via link |
| 4 | PasswordResetCompleteView |
password_reset_complete.html |
Confirmation that password was changed |
Step 1: Add Password Reset URLs
from django.contrib.auth import views as auth_views
from django.urls import path
urlpatterns = [
path('forgot-password/', auth_views.PasswordResetView.as_view(
template_name='password_reset.html'
), name='password_reset'),
path('forgot-password/done/', auth_views.PasswordResetDoneView.as_view(
template_name='password_reset_done.html'
), name='password_reset_done'),
path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(
template_name='password_reset_confirm.html'
), name='password_reset_confirm'),
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(
template_name='password_reset_complete.html'
), name='password_reset_complete'),
]
Step 2: Configure Email Backend (for development)
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
DEFAULT_FROM_EMAIL = 'noreply@yourdomain.com'
For production, switch to SMTP or a transactional email service like SendGrid, Mailgun, or Amazon SES.
Step 3: Create Templates
Django expects the following templates by default:
password_reset.htmlpassword_reset_done.htmlpassword_reset_confirm.htmlpassword_reset_complete.html
Example:
password_reset.html
<div class="container py-5">
<h2 class="mb-4">Reset your password</h2>
<p>Enter the email address associated with your account. We’ll send you a link to reset your password.</p>
<form method="post">
{{ form.email.label_tag }}
{{ form.email }}
<button type="submit" class="btn btn-primary mt-3">Send reset link</button>
</form>
</div>
password_reset_done.html
<div class="container py-5">
<h2 class="mb-4">Check your email</h2>
<p>If an account exists with the email you entered, a password reset link has been sent.</p>
<a href="/" class="btn btn-secondary mt-3">Return home</a>
</div>
password_reset_confirm.html
<div class="container py-5">
<h2 class="mb-4">Create a new password</h2>
{% if validlink %}
<form method="post">
{{ form.as_p }}
<button type="submit" class="btn btn-primary mt-3">Reset password</button>
</form>
{% else %}
<p class="text-danger">This password reset link is invalid or has expired.</p>
{% endif %}
</div>
password_reset_complete.html
<div class="container py-5">
<h2 class="mb-4">Password reset successful</h2>
<p>Your password has been updated. You can now log in with your new credentials.</p>
<a href="{% url 'login' %}" class="btn btn-primary mt-3">Log in</a>
</div>
You can fully customize these templates with Bootstrap or your site’s design to match your branding.
Step 4: Test the Flow
- Visit
/forgot-password/ - Enter a registered user’s email
- Check your console (or email inbox if SMTP is set)
- Click the reset link and set a new password
- You’ll be redirected to a success page
Optional: Customize Email Template
Django uses the following default templates for email:
registration/password_reset_email.htmlregistration/password_reset_subject.txt
Example HTML Email:
<p>You're receiving this email because you requested a password reset for your user account.</p>
<p>Please go to the following page and choose a new password:</p>
<p><a href="{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}">Reset Password</a></p>
<p>If you didn’t request this, ignore this email.</p>
Email subject template:
Reset your password
Final Tips
- Use
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'in production. - Ensure your domain is correct in the email context.
- You can override
form_classif you want to customize the input form.
Conclusion
By using Django’s built-in password reset views and email system, you can implement a fully functional, secure, and user-friendly password reset system with minimal effort. You only need to connect the views via URLs, configure email settings, and style the templates as you wish.