Django REST Password Reset
django-rest-passwordreset is an extension for Django REST Framework that provides a configurable password reset strategy. It handles token generation, validation, and password setting endpoints. The current version is 1.5.0, and it maintains an active release cadence, frequently updating to support newer Django and DRF versions.
Common errors
-
ModuleNotFoundError: No module named 'django_rest_passwordreset'
cause The 'django_rest_passwordreset' app is not added to your Django project's INSTALLED_APPS.fixAdd 'django_rest_passwordreset' to the `INSTALLED_APPS` list in your `settings.py` file. -
NoReverseMatch at /api/password_reset/confirm/ Reverse for 'password_reset:reset-password-confirm' not found. 'password_reset' is not a registered namespace.
cause The django-rest-passwordreset URLs are not included in your project's `urls.py` or are included with an incorrect namespace.fixEnsure your project's main `urls.py` includes `path('api/password_reset/', include('django_rest_passwordreset.urls', namespace='password_reset'))` and that the namespace matches 'password_reset'. -
User is not receiving password reset emails.
cause The signal receiver for `reset_password_token_created` has not been implemented or is not correctly registered, meaning the email sending logic is missing.fixImplement a Python function that uses `@receiver(reset_password_token_created)` to listen for the signal and send the password reset email. This function should contain your email sending logic. Refer to the quickstart example and ensure your `EMAIL_BACKEND` is configured in `settings.py`.
Warnings
- breaking Version 1.2.0 introduced significant breaking changes by dropping support for Python 2.7, Python 3.4, Django < 2.2, and Django REST Framework < 3.10. Ensure your project meets these minimum requirements.
- gotcha The library does not send password reset emails by default. You MUST implement a signal receiver for `reset_password_token_created` to handle email sending.
- gotcha By default, requests to the password reset endpoint with an unknown email address will still return a 200 OK response to prevent information leakage (i.e., revealing valid user emails).
- gotcha Projects using UUIDs as the primary key for their User model might encounter issues in versions prior to 1.5.0.
Install
-
pip install django-rest-passwordreset
Imports
- INSTALLED_APPS
'django_rest_passwordreset'
- urls
from django.urls import path, include urlpatterns = [ path('api/password_reset/', include('django_rest_passwordreset.urls', namespace='password_reset')), ] - reset_password_token_created signal
from django_rest_passwordreset.signals import reset_password_token_created from django.dispatch import receiver
Quickstart
# settings.py
INSTALLED_APPS = [
# ...
'rest_framework',
'django_rest_passwordreset',
]
# urls.py
from django.urls import path, include
from django.dispatch import receiver
from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives
from django_rest_passwordreset.signals import reset_password_token_created
urlpatterns = [
# ...
path('api/password_reset/', include('django_rest_passwordreset.urls', namespace='password_reset')),
]
# signals.py (or anywhere appropriate in your app)
@receiver(reset_password_token_created)
def password_reset_token_created(sender, instance, reset_password_token, *args, **kwargs):
"""
Handles password reset tokens
When a token is created, an e-mail needs to be sent to the user
"""
# Example: Render HTML email content and send
context = {
'current_user': reset_password_token.user,
'username': reset_password_token.user.username,
'email': reset_password_token.user.email,
'reset_password_url': "{}?token={}".format(
instance.request.build_absolute_uri('/reset-password/confirm/'),
reset_password_token.key
)
}
# In a real app, you'd render a proper template
email_html_message = render_to_string('email/user_reset_password.html', context)
email_plaintext_message = render_to_string('email/user_reset_password.txt', context)
msg = EmailMultiAlternatives(
# title:
f"Password Reset for {reset_password_token.user.username}",
# message:
email_plaintext_message,
# from:
os.environ.get('DEFAULT_FROM_EMAIL', 'noreply@example.com'),
# to:
[reset_password_token.user.email]
)
msg.attach_alternative(email_html_message, "text/html")
msg.send()
# Example template content for 'email/user_reset_password.html' and '.txt' would be required.
# For running this quickstart example, ensure you have an SMTP server configured for Django.