Reset User Passwords in Django

June 5, 2020, 5:11 p.m.
Django · 15 min read
Reset User Passwords in Django
Last Modified: July 5, 2021, 5:38 p.m.

Django's authentication system has a wide range of built-in features and functions, including the ability to handle user permissions and passwords. User objects are at the center of this system, with the primary attributes being username, password, email, first name, and last name.

If you have created a superuser and logged in to the Django administration site, you have probably seen the ability to change your password in the admin.

But how do you implement this same password reset functionality for regular site users?

Well, Django's Authentication views help manage password resets for users without superuser status. 

In this tutorial, we will use the Django stock password reset form to allow users to send a reset password email to themselves that then links to a change password form. This allows users to reset their passwords as needed.

Let's get started.

 

NOTE: If you haven't already configured your site for users, follow  A Guide to User Registration, Login, and Logout in Django before continuing with this article. You will not be able to test the password reset if you do not have an existing user account.

 

Authentication URLs

accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']

Django has eight URL patterns associated with the authentication views. We will only be using the last four URLs related to password reset.

 

Edit mysite > urls.py

env > mysite > mysite > urls.py

"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include ('main.urls')),
    path('accounts/', include('django.contrib.auth.urls')),
]

But instead of listing the URLs individually, we can just list the 'accounts/' path.

Add this path to your project's urls.py file, in this case, the mysite > urls.py file. 

 


 

View the built-in Django password reset forms in the browser

Now we can access any of these URLs in the browser. For example, you can go to the URL in the image:

 http://127.0.0.1:8000/accounts/password_reset/

Default password reset template

These pages have all of the functionality we need for users to reset their password, but it says Django administration at the top and does not match the rest of the site.

So let's connect the password reset forms to custom templates. 

 

But first, a quick overview of each URL and their connected templates.

 


 

The default Django password reset URLs and templates

  • password_reset: connects to an email form requesting an email associated with the existing user
  • password_reset_done: presents a message saying an email was sent with further instructions on how to reset your password
  • password_reset_confirm: is a form requesting a new password for the user
  • password_reset_complete: tells the user to log in with the new password

Don't worry if this sounds confusing at first, you will get a chance to see all of the templates below.

 


 

Make a password folder containing all of the custom templates

For each of the four URLs, we will create a custom template.

For organization purposes, let’s create a new folder called password in the templates > main folder.

Within it, add each of the HTML templates listed below. Be careful not to make a spelling mistake.

 

Create password_reset.html

env > mysite > main > templates > main > (New Folder) password > (New File) password_reset.html

{% extends 'main/header.html' %}


{% block content %}

	{% load crispy_forms_tags %}          

	<!--Reset Password-->
	<div class="container p-5">
  	 	<h2 class="font-weight-bold mt-3">Reset Password</h2>
		<hr>
		<p>Forgotten your password? Enter your email address below, and we'll email instructions for setting a new one.</p>
        <form method="POST">
            {% csrf_token %}
            {{ password_reset_form|crispy }}                    
            <button class="btn btn-primary" type="submit">Send email</button>
        </form>
  	</div> 

{% endblock %}

 

Create password_reset_done.html

env > mysite > main > templates > main > password > (New File) password_reset_done.html

{% extends 'main/header.html' %}


{% block content %}

	<!--Password reset sent-->
	<div class="container p-5">
  	<h2 class="font-weight-bold mt-3">Password reset sent</h2>
		<hr>
		<p>We've emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.<br>If you don't receive an email, please make sure you've entered the address you registered with, and check your spam folder.</p>
  </div>

{% endblock %}

 

Create password_reset_confirm.html

env > mysite > main > templates > main > password > (New File) password_reset_confirm.html

{% extends "main/header.html" %}

{% block content %}

  {% load crispy_forms_tags %}  
  
  <!--Password Reset Confirm-->
    <div class="container p-5">
	    <h2 class="font-weight-bold mt-3">Password Reset Confirm</h2>
		<hr>
        <p>Please enter your new password.</p>
        <form method="POST">
            {% csrf_token %}
            {{ form|crispy }}                    
            <button class="btn btn-primary" type="submit">Reset password</button>
        </form>
    </div>

{% endblock %}

 

Create password_reset_complete.html

env > mysite > main > templates > main > password > (New File) password_reset_complete.html

{% extends "main/header.html" %}

{% block content %} 
  
  <!--Password Reset Complete-->
    <div class="container p-4">
	    <h2 class="font-weight-bold mt-3">Password reset complete</h2>
		<hr>
        <p>Your password has been set. You may go ahead and log in now.</p>                 
        <a href="/login" class="btn btn-primary">Log in</a>
    </div>

{% endblock %}

Note that all of these templates are extending the header.html that contains the Bootstrap CDN.

The forms are also using django-crispy-forms, a Python package used to quickly style Django forms. 

 


 

Connect the templates to the URLs

Update mysite > urls.py

env > mysite > mysite > urls.py

"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views #import this


urlpatterns = [
    path('', include ('main.urls')),
    path('admin/', admin.site.urls),
    #path('accounts/', include('django.contrib.auth.urls')),
    path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(template_name='main/password/password_reset_done.html'), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name="main/password/password_reset_confirm.html"), name='password_reset_confirm'),
    path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='main/password/password_reset_complete.html'), name='password_reset_complete'),      
]

Now that we have custom templates, we need to assign them to the existing URL patterns.

First, let's import auth_views at the top of the page.

Then we can comment out the 'accounts/' URL and add three new template paths that specify each template_name

If you did not place all of the password reset templates in a password folder, your template_name will have the format 'main/password_reset_done.html'.

 


 

Make a password reset email

Create password_reset_email.txt

env > mysite > main > templates > main > password > (New File) password_reset_email.txt

{% autoescape off %}
Hello,

We received a request to reset the password for your account for this email address. To initiate the password reset process for your account, click the link below.

{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}

This link can only be used once. If you need to reset your password again, please visit {{ protocol }}://{{domain}} and request another reset.

If you did not make this request, you can simply ignore this email.

Sincerely,
The Website Team

{% endautoescape %}

The last file we need to add in the password folder is a text file containing the reset instructions.

 


 

Add a reset password URL to the main > urls.py

env > mysite > main > urls.py

from django.urls import path
from . import views

app_name = "main"   


urlpatterns = [
    path("", views.homepage, name="homepage"),
    ...
    path("password_reset", views.password_reset_request, name="password_reset")
]

Now, to send the email to the user, we need to add a password_reset view that connects to the template but also allows us to send an email via a view function. 

Add the password_reset path to the main > urls.py file. If you do not have a main > urls.py file, visit Django Quick Start Guide to Basic Configurations.

 


 

Sending the reset password email through the views.py

env > mysite > main > views.py

from django.shortcuts import render, redirect
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.models import User
from django.template.loader import render_to_string
from django.db.models.query_utils import Q
from django.utils.http import urlsafe_base64_encode
from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes



def password_reset_request(request):
	if request.method == "POST":
		password_reset_form = PasswordResetForm(request.POST)
		if password_reset_form.is_valid():
			data = password_reset_form.cleaned_data['email']
			associated_users = User.objects.filter(Q(email=data))
			if associated_users.exists():
				for user in associated_users:
					subject = "Password Reset Requested"
					email_template_name = "main/password/password_reset_email.txt"
					c = {
					"email":user.email,
					'domain':'127.0.0.1:8000',
					'site_name': 'Website',
					"uid": urlsafe_base64_encode(force_bytes(user.pk)),
					"user": user,
					'token': default_token_generator.make_token(user),
					'protocol': 'http',
					}
					email = render_to_string(email_template_name, c)
					try:
						send_mail(subject, email, 'admin@example.com' , [user.email], fail_silently=False)
					except BadHeaderError:
						return HttpResponse('Invalid header found.')
					return redirect ("/password_reset/done/")
	password_reset_form = PasswordResetForm()
	return render(request=request, template_name="main/password/password_reset.html", context={"password_reset_form":password_reset_form})

We need to add a view function that sends an email to the user if their email connects to an existing user account.

Specify the subject of the email along with the email template we want to send. Then we can pass in all of the information needed for the email's content, such as the email, domain, uid, and token. The last two values of the dictionary are what generates the unique domain slug that allows the user to only reset their password. 

The last thing to add is the send_mail function that passes in the subject, email, from, and to addresses before redirecting the user to the /password_reset/done page.

Keep in mind this function is configured to send the reset email to your Terminal, not an actual email address.

During production, the domain, site name, protocol, and from email address will need to be changed. 

Please note, if you are using Django version 2.1 or older, you need to add decode() to your uid to convert the byte literal from a byte type to a string type.

"uid": urlsafe_base64_encode(force_bytes(user.pk)).decode()

 


 

Configuring the settings.py to send emails

env > mysite > main > settings.py

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

But seeing how we are only testing, make sure you have added the EMAIL_BACKEND listed above to the settings file so we can send the email to the CLI.

For production, the backend is changed to an email sending service.

 


 

Test the password reset email

To access the new password reset page, you can just type in http://127.0.0.1:8000/password_reset or you can add <a href="/password_reset">Forgot password?</a> to your login page.

Either way, go to this page in your browser and type in an email address connected to an existing user account.

Custom Password reset form

 

Once you get the /password_reset/done page, open your CLI and you should see a similar message to the one below. 

Custom email template sent

Terminal

[05/Jun/2020 17:07:29] "POST /password_reset HTTP/1.1" 500 80466
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Password Reset Requested
From: admin@example.com
To: admin@example.com
Date: Sat, 06 Jun 2020 00:11:42 -0000


Hello,

We received a request to reset the password for your account for this email address. To initiate the password reset process for your account, click the link below.

http://127.0.0.1:8000/reset/<uid>/<token>/

This link can only be used once. If you need to reset your password again, please visit http://127.0.0.1:8000 and request another reset.

If you did not make this request, you can simply ignore this email.

Sincerely,
The Website Team


-------------------------------------------------------------------------------

 

You will need to copy the exact link sent to the CLI and paste it in your browser to view the change password page. You will then enter and confirm your new password.

Custom confirm password form

 

Once that is complete, you will get the password reset complete page that instructs you to log in with your new password. 

Login in with new password

 


 

Use Django Messages framework with Django Password Reset

In the example above, we chose to add a redirect to the /password_reset/done page when the password_reset form was submitted correctly, but instead, we can choose to use Django messages to notify the user that an email has been sent to their inbox.

To do this, we just have to configure the project to use the Django Messages Framework then add the message to the view function.

 

Add a Django success message

env > mysite > main > views.py

from django.shortcuts import render, redirect
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.models import User
from django.template.loader import render_to_string
from django.db.models.query_utils import Q
from django.utils.http import urlsafe_base64_encode
from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes
from django.contrib import messages #import messages

def homepage(request):
	return render (request=request, template_name="main/home.html")

def password_reset_request(request):
	if request.method == "POST":
		password_reset_form = PasswordResetForm(request.POST)
		if password_reset_form.is_valid():
			data = password_reset_form.cleaned_data['email']
			associated_users = User.objects.filter(Q(email=data))
			if associated_users.exists():
				for user in associated_users:
					subject = "Password Reset Requested"
					email_template_name = "main/password/password_reset_email.txt"
					c = {
					"email":user.email,
					'domain':'127.0.0.1:8000',
					'site_name': 'Website',
					"uid": urlsafe_base64_encode(force_bytes(user.pk)),
					'token': default_token_generator.make_token(user),
					'protocol': 'http',
					}
					email = render_to_string(email_template_name, c)
					try:
						send_mail(subject, email, 'admin@example.com' , [user.email], fail_silently=False)
					except BadHeaderError:

						return HttpResponse('Invalid header found.')
						
					messages.success(request, 'A message with reset password instructions has been sent to your inbox.')
					return redirect ("main:homepage")
	password_reset_form = PasswordResetForm()
	return render(request=request, template_name="main/password/password_reset.html", context={"password_reset_form":password_reset_form})

See How to use Django Messages Framework first to learn the project configurations necessary for Django messages, then add a success message before the return that now redirects to the homepage rather than password_reset/done.

Save the file.

You can then delete the password_reset_done.html and the URL pattern to that template. 

Now, when the user submits the reset password form, a message will appear instead of the template. 

Password reset with messages

 

Add a Django error message: Update main > views.py

env > mysite > main > views.py

from django.shortcuts import render, redirect
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.models import User
from django.template.loader import render_to_string
from django.db.models.query_utils import Q
from django.utils.http import urlsafe_base64_encode
from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes
from django.contrib import messages #import messages

def homepage(request):
	return render (request=request, template_name="main/home.html")

def password_reset_request(request):
	if request.method == "POST":
		password_reset_form = PasswordResetForm(request.POST)
		if password_reset_form.is_valid():
			data = password_reset_form.cleaned_data['email']
			associated_users = User.objects.filter(Q(email=data))
			if associated_users.exists():
				for user in associated_users:
					subject = "Password Reset Requested"
					email_template_name = "main/password/password_reset_email.txt"
					c = {
					"email":user.email,
					'domain':'127.0.0.1:8000',
					'site_name': 'Website',
					"uid": urlsafe_base64_encode(force_bytes(user.pk)),
					'token': default_token_generator.make_token(user),
					'protocol': 'http',
					}
					email = render_to_string(email_template_name, c)
					try:
						send_mail(subject, email, 'admin@example.com' , [user.email], fail_silently=False)
					except BadHeaderError:

						return HttpResponse('Invalid header found.')
						
					messages.success(request, 'A message with reset password instructions has been sent to your inbox.')
					return redirect ("main:homepage")
			messages.error(request, 'An invalid email has been entered.')
	password_reset_form = PasswordResetForm()
	return render(request=request, template_name="main/password/password_reset.html", context={"password_reset_form":password_reset_form})

You can also choose to add an error message outside of the if condition that appears if the associated user does not exist within the database.

 


 

Sending emails in production

The Django settings.py and views.py configurations above are meant for testing in development mode. They will not work once your Django app is deployed and in production.

To configure your Django app for production:

  1. Sign up for an SMTP email service
  2. Update your settings.py with the new email_backend
  3. Update your views.py password_reset_request function

 

For this tutorial we will be using AWS SES, an email service provided through Amazon Web Services 12-month free tier.

 

Sending emails with AWS Simple Email Services

Create a free AWS account at https://aws.amazon.com/free/.

After creating an account, you need to connect your Django project to your AWS account.

Visit the tutorial, Setting up AWS SES Email Backend for Production for in-depth instructions on how to complete the Django AWS SES integrations. 

Please note: AWS SES only allows emails to be sent and received by an AWS verified email address unless you upgrade your account out of the AWS SES sandbox.

 

Updates to the Django settings.py

env > mysite > main > settings.py

# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

EMAIL_BACKEND = 'django_ses.SESBackend'
AWS_ACCESS_KEY_ID = 'YOUR-ACCESS-KEY-ID'
AWS_SECRET_ACCESS_KEY = 'YOUR-SECRET-ACCESS-KEY'
AWS_SES_REGION_NAME = 'REGION-NAME' #(ex: us-east-2)
AWS_SES_REGION_ENDPOINT ='REGION-ENDPOINT' #(ex: email.us-east-2.amazonaws.com)

After following the instructions for sending emails with AWS SES, your settings.py file should look like the setting above. 

As for the AWS SES region name, you have the following 13 regions are supported:

  • us-east-1 (US East - N. Virginia)
  • us-east-2 (US East - Ohio)
  • us-west-2 (US West - Oregon)
  • ap-south-1 (Asia Pacific - Mumbai)
  • ap-northeast-2 (Asia Pacific - Seoul)
  • ap-southeast-1 (Asia Pacific - Singapore)
  • ap-southeast-2 (Asia Pacific - Sydney)
  • ap-northeast-1 (Asia Pacific - Tokyo)
  • ca-central-1 (Canada - Central)
  • eu-central-1 (Europe - Frankfurt)
  • eu-west-1 (Europe - Ireland)
  • eu-west-2 (Europe - London)
  • sa-east-1 (South America - São Paulo)

If you do not live in one of these regions, select a region that is closest to you. 

 

EXAMPLE - Updated the settings.py

env > mysite > main > settings.py (EXAMPLE)

# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

EMAIL_BACKEND = 'django_ses.SESBackend'
AWS_ACCESS_KEY_ID = 'don45nogo45ouyho45hy5'
AWS_SECRET_ACCESS_KEY = 'orebgojtiopj45tpngpnerpg'
AWS_SES_REGION_NAME = 'ap-southeast-2'
AWS_SES_REGION_ENDPOINT ='email.ap-southeast-2.amazonaws.com'

For clarification, here is a more accurate example of my settings.py with (fake) AWS secret access keys and region filled in.

If my region is Asia Pacific - Sydney, my AWS region name would be ap-southeast-2 and my AWS region endpoint email.ap-southeast-2.amazonaws.com.

 

 

Updates to the Django views.py

env > mysite > main > views.py

from django.shortcuts import render, redirect
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse
from django.contrib.auth.forms import PasswordResetForm
from django.contrib.auth.models import User
from django.template.loader import render_to_string
from django.db.models.query_utils import Q
from django.utils.http import urlsafe_base64_encode
from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes
from django.contrib import messages #import messages

def homepage(request):
	return render (request=request, template_name="main/home.html")

def password_reset_request(request):
	if request.method == "POST":
		password_reset_form = PasswordResetForm(request.POST)
		if password_reset_form.is_valid():
			data = password_reset_form.cleaned_data['email']
			associated_users = User.objects.filter(Q(email=data))
			if associated_users.exists():
				for user in associated_users:
					subject = "Password Reset Requested"
					email_template_name = "main/password/password_reset_email.txt"
					c = {
					"email":user.email,
					'domain':'your-website-name.com',
					'site_name': 'Website Name',
					"uid": urlsafe_base64_encode(force_bytes(user.pk)),
					'token': default_token_generator.make_token(user),
					'protocol': 'https',
					}
					email = render_to_string(email_template_name, c)
					try:
						send_mail(subject, email, 'AWS_verified_email_address', [user.email], fail_silently=False)
					except BadHeaderError:

						return HttpResponse('Invalid header found.')
						
					messages.success(request, 'A message with reset password instructions has been sent to your inbox.')
					return redirect ("main:homepage")
			messages.error(request, 'An invalid email has been entered.')
	password_reset_form = PasswordResetForm()
	return render(request=request, template_name="main/password/password_reset.html", context={"password_reset_form":password_reset_form})

As for the views.py, you need to change the domain listed in the dictionary from 'domain':'127.0.0.1:8000' to the actual name of your website.

Then you need to change the 'protocol' from 'http' to 'https', if you are using HTTPS.

Finally, update the send_mail function with your verified AWS SES email address. To get a verified AWS email address, you need to set up an AWS SES Email Backend.

 


 

Customizing the Django reset email template

The reset password email currently sends as a plain text email.

If you are interested in making it into an HTML email template, check out the article Using HTML Email Templates for Password Reset Emails

Reset Password email as an HTML template

 






Post a Comment
Join the community

34 Comments
Stelity Oct. 18, 2020, 11:41 p.m.

This only works for people who are verified on SES. When I send an email to someone who isn't verified on AWS SES, I get: "An error occurred (MessageRejected) when calling the SendRawEmail operation: Email address is not verified."

Jaysha replying to Stelity Oct. 19, 2020, 9:42 a.m.

All new AWS SES accounts are held in sandbox unless you request production access. The article now reflects this and links to the AWS SES sandbox instructions.

Mohsen Oct. 31, 2020, 12:35 p.m.

Very helpful. Thank you

Andres Nov. 19, 2020, 3:12 p.m.

This was such a helpful article - can't thank you enough! Had a requirement to move away from a third-party SMTP service and use an internal email client (not fun). This article helped me override the main emails and use a custom send function! THANK YOU!

Jaysha replying to Andres Jan. 6, 2021, 11:48 a.m.

Glad to help!

Jigme Jan. 29, 2021, 11:45 p.m.

i m geting the default password reset form although i have wriiten same as you. What could be my problem

Jaysha replying to Jigme Feb. 2, 2021, 12:03 p.m.

Be sure to comment out the 'accounts/' path and add the 'password_reset/done', 'reset/<uid64>/<token>/', and 'reset/done/' paths in the mysite >urls.py file. Then add the 'password_reset' path to the main > urls.py file.

Jaysha replying to Jigme Feb. 2, 2021, 12:04 p.m.

You should have the connected password_reset_request function in the views.py. Then you can go to http://127.0.0.1:8000/password_reset and your custom template should appear. You no longer need to go to http://127.0.0.1:8000/accounts/password_reset/.

Leah March 11, 2021, 10 a.m.

Hi, I'm getting "Cannot resolve keyword 'is_active' into field", when I've added "path('accounts/', include('django.contrib.auth.urls'))," to my "urls.py" file. Do you know what might be causing this?

Jaysha replying to Leah March 12, 2021, 10:47 a.m.

It seems like you're trying to query the User model using the field is_active but that field doesn't exist. Your error message should include a list of available field choices, one of which is active. Switch is_active for active and that should solve it.

Devika March 29, 2021, 11:44 a.m.

Hi I have tried this code, but in my project I am getting email to the superuser only, not getting email to the ordinary user, who is registered to the site. Kindly help me out

Jaysha replying to Devika March 30, 2021, 9:57 a.m.

Hi Devika, check to make sure the superuser and the regular user don't have the same email address listed in the admin. Then be sure to enter the regular user's email in the reset password form. Let me know if that solves your problem!

Devika replying to Jaysha March 31, 2021, 12:25 a.m.

Hi , Thanks for your Reply. I have resolved the User issue, which I used the admin default User. Now all the users are receiving email but post clicking the reset link which received via mail, it is displaying as link is not valid as it has been used.

Jaysha replying to Devika March 31, 2021, 8:37 p.m.

Hi Devika, I'm happy the first problem was solved! The autogenerated password reset link can only be used once. If you try and access the same link again after resetting the password, you're met with the same Password Reset Confirm page without a form.

Devika replying to Jaysha March 31, 2021, 11:23 p.m.

Hi Jaysha, Thanks for your reply, but the problem is when I click on fresh link immediately I am getting error as invalid link.

Jaysha replying to Devika March 31, 2021, 8:42 p.m.

You have to go back to the http://127.0.0.1:8000/password_reset page and submit a new password reset request to get a new autogenerated link that works. I hope that clears things up.

Devika replying to Jaysha April 2, 2021, 8:17 p.m.

Hi Jaysha, actually I am not using the default User in Django, I have created a separate register model and using the same model for resetting password. In such cases, how can I use these functionality? Is it the reason for invalid email link?

Jaysha replying to Devika April 5, 2021, 2:45 p.m.

Hi Devika, I'd recommend using the Django user authentication system because it already handles all the user authentication and authorization for you. This tutorial uses this system given that it already comes with the stock auth forms and validation.

Jaysha replying to Jaysha April 5, 2021, 2:47 p.m.

Extend the existing User model to a new model if you're looking to add additional information. Here's a helpful resource: https://docs.djangoproject.com/en/3.1/topics/auth/customizing/

Devika replying to Jaysha April 6, 2021, 5:47 a.m.

Hi Jaysha, Thanks a lot for your quick and apt reply.. Resolved my issues .

Jaysha replying to Devika April 6, 2021, 4:53 p.m.

Happy to hear that!

Daoud April 29, 2021, 9:25 p.m.

thank you so much <3

Jaysha replying to Daoud May 5, 2021, 11:37 a.m.

No problem!

Virender May 14, 2021, 6:22 a.m.

EMAIL_HOST = "smtp.gmail.com" EMAIL_POST = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = os.environ.get('EMAIL_USER') EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_PASS') i am using this in setting file .can you please configure view file for this code

Alexander June 22, 2021, 7:19 a.m.

I'm not getting the field to fill out the new password and if I run it without the template I get "the link has expired..."

Jaysha replying to Alexander July 5, 2021, 5:26 p.m.

Hi Alexander, you need to either upgrade Django to a version > 2.1 or add decode() to the end of your uid in the views.py like this: urlsafe_base64_encode(force_bytes(user.pk)).decode()

Jaysha replying to Jaysha July 5, 2021, 5:29 p.m.

The uid is bytes literal, formatted like b'Mg'. Older versions of Django require you decode the bytes type into a string type using decode(). Hope that helps!

Abhishek3 June 30, 2021, 5:15 a.m.

thank u so much

Asha July 3, 2021, 4:17 a.m.

Hi, I'm not getting reset password confirm form instead of getting "please enter your password" and "submit" button only. I have written same as you. What will do....?

Jaysha replying to Asha July 5, 2021, 5:31 p.m.

Hi Asha, refer to the answer I provided Alexander above. This should solve your problem.

Alterego July 5, 2021, 6:23 a.m.

Hi, is there a way to make it so the new password is different from the previous?

Jaysha replying to Alterego July 5, 2021, 5:57 p.m.

These resources should help: https://stackoverflow.com/questions/32464432/store-old-password-hashes-in-django-so-users-cant-reuse-the-same-password and https://gonzalo123.com/2020/09/21/dont-repeat-password-validator-in-django/

Sindhu July 25, 2021, 3:55 a.m.

Hello,mam.I am getting this error'utf-8' codec can't decode byte 0x92 in position 25: invalid start byte, please help me to resolve this

Raoul July 26, 2021, 4:12 a.m.

Great article, thanks for saving me a lot of time figuring this out myself! :)

13
Jaysha
Written By
Jaysha
Hello! I enjoy learning about new CSS frameworks, animation libraries, and SEO.