I'm using django-rest-auth and I am trying to fix a bug in the password reset view by overwriting one of the form's methods. Although I've successfully done something similar with a different django-rest-auth form, I can't make it work on this one. Whatever I do, the old form is used.
api/urls.py
from django.urls import include, path
from django.contrib.auth import views
from django.conf.urls import include, url
from django.views.generic.base import RedirectView
from .forms import SetPasswordFormCustom
from .forms import PasswordResetFormCustom
urlpatterns = [
path('password/reset/',
views.PasswordResetView.as_view(form_class=PasswordResetFormCustom),
name='rest_password_reset'),
path('rest-auth/', include('rest_auth.urls')),
path('rest-auth/registration/', include('rest_auth.registration.urls')),
path('users/', include('users.urls')),
path('reset/<uidb64>/<token>/',
views.PasswordResetConfirmView.as_view(template_name='account/password_reset_confirm.html', form_class=SetPasswordFormCustom),
name='password_reset_confirm'),
path('reset/done/', views.PasswordResetCompleteView.as_view(template_name='account/password_reset_complete.html'),
name='password_reset_complete'),
path('content/', include('lists.endpoints')),
# content is a path for lists, items etc found in the lists app
]
forms.py
from django import forms
from django.contrib.auth.forms import SetPasswordForm
from django.contrib.auth import (
authenticate, get_user_model, password_validation,
)
from django.utils.translation import gettext, gettext_lazy as _
#from django.contrib.auth import password_validation
from django.contrib.auth.forms import PasswordResetForm
UserModel = get_user_model()
class SetPasswordFormCustom(SetPasswordForm):
new_password1 = forms.CharField(
label=_("New password"),
widget=forms.PasswordInput(attrs={'class':'form-control','placeholder':'Password'}),
strip=False,
)
new_password2 = forms.CharField(
label=_("Confirm new password"),
strip=False,
widget=forms.PasswordInput(attrs={'class':'form-control','placeholder':'Confirm password'}),
help_text=password_validation.password_validators_help_text_html(),
)
class PasswordResetFormCustom(PasswordResetForm):
def get_users(self, email):
print('using custom form');
"""Given an email, return matching user(s) who should receive a reset.
This allows subclasses to more easily customize the default policies
that prevent inactive users and users with unusable passwords from
resetting their password.
"""
active_users = UserModel._default_manager.filter(**{
'%s__iexact' % UserModel.get_email_field_name(): email,
'is_active': True,
})
if not active_users:
raise forms.ValidationError(_("The e-mail address is not assigned to any user account"),
code='invalid')
return (u for u in active_users if u.has_usable_password())
So, what I can't figure out is that PasswordResetFormCustom with its check for active_users, is not used. The line "using custom form" is not printed in the server log when I request a password reset email, and the check is not performed.
My other custom form PasswordResetConfirmView works fine.
There are no errors so it isn't that the imports are incorrect.
Any idea how I can customise the get_users method without having to edit the django-rest-auth file?
Thanks for any help!
Edit: I put yofee's code into a file serializers.py, and also I had to fix the order of my url paths in urls.py. Now it works!
urlpatterns = [ ... path('rest-auth/password/reset/', PasswordResetView.as_view()), path('rest-auth/', include('rest_auth.urls')), ... ]
reset path must come before the include.