Reputation: 2307
I am building a user authentication backend with djano
using rest_auth
and allauth
. This is my api
app's urls.py
urlpatterns = [
path('rest-auth/', include('rest_auth.urls')),
path('rest-auth/registration/', include('rest_auth.registration.urls')),
path("account/", include('allauth.urls')),
]
after running server, I am going to rest-auth/password/reset
, type in the email and post.
an error occurs saying:
NoReverseMatch at /api/v1/rest-auth/password/reset/
Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.
I found this SO question which helped: NoReverseMatch at /rest-auth/password/reset/
and after looking at the django REST framework official demo: https://django-rest-auth.readthedocs.io/en/latest/demo.html,
I included other endpoints in my url.py as suggested:
urlpatterns = [
# rest framework authentication: login/logout/signup etc ...
path('rest-auth/', include('rest_auth.urls')),
# url endpoint for registration
path('rest-auth/registration/', include('rest_auth.registration.urls')),
# url endpoint to confirm email for change of password
path('password-reset/confirm', TemplateView.as_view(template_name="password_reset_confirm.html"), name="password-reset-confirm"),
# url link to change password (sent via email)
path('password-reset/confirm/<uidb64>/<token>/', TemplateView.as_view(template_name="password_reset_confirm.html"), name='password_reset_confirm'),
# to handle different account emails (facebook, github, gmail, etc .. )
path("account/", include('allauth.urls')),
]
where I also included my simple html
landing page when resettinthe g password. This works. an email is sent with a confirmation link and the html
pages load up. however after I confirm my email in my custom pages, the default page for the django REST auth password reset appears and I have to input the new password there again for the change in password to take effect.
Now at the moment, I would rather just use the Django rest template than my own. so is there a way to not call template_name="password_reset_confirm.html"
and go directly to the django default?
or otherwise go directly to the django rest-auth/password/reset/confirm
rather than my custom 'password-reset/confirm'
, which I only implemented to get rid of the error I mentioned.
what is the optimal solution?
Upvotes: 2
Views: 3774
Reputation: 2307
Found the answer myself. Daniel Roseman's is a good answer however if you want to use the Django rest framework's rest-auth
for resetting the password with email confirmation, the below urlpatterns
is the correct one:
from django.urls import include, path
from rest_auth import views
urlpatterns = [
path('rest-auth/', include('rest_auth.urls')),
path('rest-auth/registration/', include('rest_auth.registration.urls')),
path('rest-auth/password/reset/confirm/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name="password_reset_confirm"),
path("account/", include('allauth.urls')),
]
The missing knowledge in my case was the views.PasswordResetConfirmView
which is the default view for resetting the password in rest-auth
Upvotes: 3
Reputation: 599490
I don't understand why you have done this. There's no point assigning those URLs to TemplateViews, they won't have the right functionality to actually do the reset etc.
I think you are confusing URLs, templates and views. What you actually need to do is to create the relevant URLs, but point them at the existing Django views.
from django.contrib.auth import views
urlpatterns = [
path('password_reset/', views.PasswordResetView.as_view(), name='password_reset'),
path('password_reset/done/', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset/done/', views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
Upvotes: 1
Reputation: 343
You do not need to add the reverse urls to your urls.py. Take this register function for example. There is a function redirect that will redirect you to the login page when successfully registered
@login_required
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'An Account has been created for the user {username}.')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
Upvotes: 0