I have found many similar questions to this issue. This question was one of them, but it didn't solve my problem, so I will ask my own question.
I'm making a password reset page on my website. But when I go to http://localhost:8000/users/reset-password and enter my email and clicks on 'Reset my password', then Django throws a NoReverseMatch error at me.
The error is:
NoReverseMatch at /users/reset-password/
Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.
I believe there's something wrong with how I write my urlpatterns.
I've tried:
Making my own views and templates.
Rewriting all my urlpatterns.
My Code
urls.py:
"""Defines URL Patterns for users."""
from django.urls import re_path
from django.contrib.auth.views import (
LoginView, PasswordResetView, PasswordResetConfirmView,
PasswordResetDoneView,
)
from . import views
urlpatterns = [
# Login Page.
re_path(r'^login/$', LoginView.as_view(template_name='users/login.html'),
name='login'),
# Logout Page.
re_path(r'^logout/$', views.logout_view, name='logout'),
# Registration Page.
re_path(r'^register/$', views.register, name='register'),
# Password reset Page.
re_path(r'^password_reset/$', PasswordResetView.as_view(
# This is the only line I added in this file.
template_name='users/password_reset_email.html'
),
name='password_reset'),
# Password reset done Page.
re_path(r'^password_reset/done/$', PasswordResetDoneView.as_view(),
name='password_reset_done'),
# Password reset confirm Page.
re_path(r'^password_reset/confirm/'
+ '(?P<uidb64>[0-9A-Za-z]+)/(?P<token>.+)/$',
PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
]
My own users/password_reset_email.html:
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'users:password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
Update:
I got something right. Now I get a NoReverseMatch at /users/password_reset/
Reverse for 'password_reset_confirm' with keyword arguments '{'uidb64': '', 'token': ''}' not found. 1 pattern(s) tried: ['users/password_reset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$']. I got to this error by using my own template of djangos password_reset_email.html, where I modified the line: {% url 'password_reset_confirm' uidb64=uid token=token %} to {% url 'users:password_reset_confirm' uidb64=uid token=token %}. Now i'm almost certain that i'm just writing my urls or regexes wrong.
I have edited my question to show the new code.
I finally got it.
Here is the answer to the problem.
Now I get a ConnectionRefusedError, which means that I now only need to set up an SMTP Server for emails, and then it should work! The thing I was missing all the time was, that I wasn't pointing out what email template I wanted to use. I just set the email template as the template, so Django couldn't render it correctly. Here is the updated code for urls.py where path(r'password-reset/') is changed:
from django.urls import path, reverse_lazy
import django.contrib.auth.views as auth_views
from . import views
urlpatterns = [
# Login Page.
path(r'login/', auth_views.LoginView.as_view(
template_name='users/login.html'
),
name='login'),
# Logout Page.
path(r'logout/', views.logout_view, name='logout'),
# Registration Page.
path(r'register/', views.register, name='register'),
# Password reset page.
path(r'password-reset/', auth_views.PasswordResetView.as_view(
email_template_name='users/password_reset_email.html',
success_url=reverse_lazy('users:password_reset_done')
), name='password_reset'),
# Password reset done page.
path(r'password-reset/done/',
auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done'),
# Password reset confirm page.
path(r'password-reset/confirm/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm')
]
Everything else is correct.
I got the answer from this answer.
Related
I am currently working on a website where you can create a shopping list. I am trying to insert items into the shoplist. So things like banana, cake, etc would go into shoplist. I got everything to work. When I create the item, it goes inside the database but when I try to redirect back to the website where I pressed create item, it shows the error
Reverse for 'detail' with keyword arguments '{'pk': 1}' not found. 1 pattern(s) tried: ['shoplist/(?P<item_id>[0-9]+)/$']
Also, when I try to enter my details page, it shows the error
Reverse for 'createitem' with arguments '('',)' not found. 1 pattern(s) tried: ['shoplist/(?P<item_id>[0-9]+)/createitem/$']
I think I did something wrong when making my paths or doing something wrong syntax wise. Nothing I found on the internet is fixing it. Is there a way to fix this problem? Thank you very much!
views.py
def createitem(request, item_id):
if request.method == 'GET':
return render(request, 'shoplist/createitem.html', {'form':ItemForm(), 'id':item_id})
else:
form = ItemForm(request.POST)
itemlist = form.save(commit=False)
itemlist.shoplist = Shoplist.objects.filter(user=request.user, pk=item_id).first()
itemlist.user = request.user
itemlist.save()
return redirect('detail', pk=item_id)
urls.py
from django.contrib import admin
from django.urls import path
from shoplist import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
#authentication
path('signup/', views.usersignup, name='usersignup'),
path('logout/', views.userlogout, name='userlogout'),
path('login/', views.userlogin, name='userlogin'),
path('create/', views.createlist, name='createlist'),
path('shoplist/', views.currentshoplist, name='currentshoplist'),
path('shoplist/<int:item_id>/', views.detail, name='detail'),
path('shoplist/<int:item_id>/createitem/', views.createitem, name='createitem'),
]
detail.html
{% extends 'shoplist/base.html' %}
{% block content %}
<h2>{{ error }}</h2>
<h1>{{ shopitems }}</h1>
{% for i in item %}
{{i.item}}
{% endfor %}
<form action="{% url 'createitem' item_id %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create Item</button>
</form>
{% endblock %}
You want to redirect to the 'detail' view and the arg required for it is item_id as an int. I think you want redirect('detail', item_id=item_id). However, you probably want to get the created pk from the form... Maybe form.instance.pk? So redirect('detail', item_id=form.instance.pk). It's not clear if that form is for saving the same object type as you're viewing with the 'detail' view.
For the {% url %}, I don't think you can use anything but keyword args. So, {% url 'createitem' item_id=item_id %} if you put item_id into the template context.
I am using the PasswordResetView of django.contrib.auth.views. I am trying to direct my path('reset-password/'...) to use my 'rest_password_email.html' template after the user has submitted an email address for password reset. I have added this as a kwargs, however django is not recognizing it and continues to direct the application to default 'password_reset_email.html'. Any suggestions on how this can be achieved? thanks.
BTW: I am using namespace 'accounts'. Hence the reason for doing the above is to introduce the amended url in my template to account for the namespace.
url.py
from django.urls import path
from . import views
from django.contrib.auth.urls import urlpatterns
from django.contrib.auth.views import (
LoginView, LogoutView,
PasswordResetView, PasswordResetDoneView,
PasswordResetConfirmView,
PasswordResetCompleteView
)
from django.urls import reverse_lazy
app_name = 'accounts'
urlpatterns = [
path('', views.home, name = 'home'),
path('column/', views.column),
path('login/', LoginView.as_view(template_name='accounts/login.html'), name = 'login'),
path('logout/', LogoutView.as_view(template_name='accounts/logout.html'), name = 'logout'),
path('register/', views.register, name = 'register'),
path('profile/', views.view_profile, name = 'view_profile'),
path('profile/edit/', views.edit_profile, name = 'edit_profile'),
path('change_password/', views.change_password, name = 'change_password'),
path('reset-password/', PasswordResetView.as_view(template_name='accounts/reset_password.html'), kwargs={'email_template_name':'accounts/reset_password_email.html','post_reset_redirect': reverse_lazy('accounts:password_reset_done')}, name = 'password_reset'),
path('reset-password/done', PasswordResetDoneView.as_view(), name = 'password_reset_done'),
path('reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', PasswordResetConfirmView.as_view(), name = 'password_reset_confirm'),
path('reset-password/complete/$', PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
reset_password_email.html
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'accounts:password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans 'Your username, in case you’ve forgotten:' %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
You can set your email_template_name in PasswordResetView,
url(r'^reset-password/$',
PasswordResetView.as_view(template_name='accounts/reset_password.html'),
{
'email_template_name': 'accounts/reset_password_email.html',
'success_url' : reverse_lazy('accounts:reset_password_done')
},
name='reset_password'),
or you can directly pass it in .as_view()
url(r'^reset-password/$',
PasswordResetView.as_view(template_name='accounts/reset_password.html',
email_template_name = 'accounts/reset_password_email.html',
success_url = reverse_lazy('accounts:reset_password_done')) ,
name='reset_password'),
The connection error issue is resolved and the reset password is working now. I was missing an Email backend in settings.py. Included: EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
I'm fairly new to django and I'm currently rewriting the django login views so I can move all the authentication process to a dedicated django app where I can redefine the templates.
So currently I have an accounts app which url.py looks like that:
from django.contrib.auth import views as auth_views
from django.urls import path
from . import views
app_name = 'accounts'
urlpatterns = [
path('login/', auth_views.login, {'template_name': 'accounts/login.html'}, name='login'),
path('logout/', auth_views.logout, name='logout'),
path('password_reset/', auth_views.password_reset,
{'template_name': 'accounts/password_reset_form.html',
'email_template_name': 'accounts/password_reset_email.html',
'subject_template_name': 'accounts/password_reset_subject.txt',
'post_reset_redirect': 'done/'}, name='password_reset'),
path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(
template_name='accounts/password_reset_done.html'), name='password_reset_done'),
path('reset/<uidb64>/<token>/', auth_views.password_reset_confirm,
{'template_name': 'accounts/password_reset_confirm.html',
'post_reset_redirect': '/accounts/reset/done/'}, name='password_reset_confirm'),
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(
template_name='accounts/password_reset_complete.html'), name='password_reset_complete')
]
And a accounts/password_reset_email.html which looks like this:
{% autoescape off %}
To initiate the password reset process for your {{ user.get_username }} account,
click the link below:
{{ protocol }}://{{ domain }}{% url 'accounts:password_reset_confirm' uidb64=uid token=token %}?origin_page={{ request.POST.origin_page }}"
...
Sincerely,
The Team
{% endautoescape %}
What I want to do is to recover the origin_page argument so when the user click on the reset link from the email he get redirected to the right webpage after his password is reset. So far I tried to do this in password_reset_form.html:
{% block content %}
<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 %}
{{ form.as_p }}
<input type="hidden" name="origin_page" value="{{ request.GET.origin_page }}"/>
<button type="submit">Submit</button>
</form>
{% endblock %}
Here I just want to pass in my origin_page to the submit form so that I can retrieve it from accounts/password_reset_email.html, the url for this page looks like this http://127.0.0.1:8000/accounts/password_reset/?origin_page=/mypage/.
How can I recover the request.POST.origin_page parameter from accounts/password_reset_email.html?
Thanks.
maybe that helps
path('password-reset/',
auth_views.PasswordResetView.as_view(
template_name='form.html',
email_template_name='email.html',
extra_email_context={
'origin_page':'origin_page_thing'
}
),
name='password_reset'),
email:
{{ protocol }}://{{ domain }}{% url 'accounts:password_reset_confirm' uidb64=uid token=token %}?origin_page={{ origin_page }}
E-Kami solution:
Ok I've got it, I actually created a new PasswordResetView like this: ' \
class PasswordResetView(auth_views.PasswordResetView):
template_name = 'commons/password_reset_form.html'
email_template_name = 'commons/password_reset_email.html'
subject_template_name = 'commons/password_reset_subject.txt'
success_url = 'done/'
def post(self, request, *args, **kwargs):
self.extra_email_context = {
'origin_page': self.request.POST['origin_page']
}
return super().post(request, *args, **kwargs)
Django version 1.11.5,
views.py
class SignupPage(CreateView):
form_class = forms.UserSignupForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
website/urls.py
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from django.contrib.auth.views import LoginView,LogoutView
from . import views
app_name = 'website'
urlpatterns = [
url(r'^login/', auth_views.LoginView.as_view(template_name='signin_2_w.html'), name='login'),
url(r'^logout/$', auth_views.LogoutView.as_view(), name='logout'),
url(r'^signup/', views.SignupPage.as_view(), name='sign_up'),
forms.py
class UserSignupForm(UserCreationForm):
class Meta:
fields = ('username','email','password1','password2')
model = get_user_model()
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.fields['username'].label = "Display Name"
self.fields['email'].label = "Email Address"
self.fields['password1'].label = "Password"
self.fields['password2'].label = "Confirm Password"
proj/urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$',views.HomePage.as_view(),name='home'),
url(r'^website/',include('website.urls',namespace='website')),
url(r'^website/',include('django.contrib.auth.urls')),
url(r'^website/',views.StreamyePage.as_view(),name='streamye'),
url(r'^thanks/$',views.ThanksPage.as_view(),name='thanks'),
url(r'^congrats/$',views.CongratsPage.as_view(),name='congrats'),
url(r'^aboutus/$',views.AboutusPage.as_view(),name='about_us'),
HTML
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li>Logout</li>
{% else %}
<li>Login</li>
<li>Signup</li>
{% endif %}
</ul>
In the above code, the signup page is throwing me a error -- "django.urls.exceptions.NoReverseMatch: Reverse for 'sign_up' not found. 'sign_up' is not a valid view function or pattern name."
Please someone help me out where im wrong!
Thanks in advance!
You have to fix the links in the template to target the website urls :
{% if user.is_authenticated %}
<li>Logout</li>
{% else %}
<li>Login</li>
<li>Signup</li>
{% endif %}
In my case, the reason was that the session cookie was corrupted due to code changes.
I solved it by opening my app url in the incognitio mode(which will create fresh session cookie),
Then try non-incognitio normal url login.
If you are using Django rest framework, this may help.
When you have router as,
router.register("path", SomeViewSet, basename="some-name")
Call the reverse as,
reverse("some-name-list")
I am using django(1.10) default password reset feature.I am getting the below error when I change the password from the password reset form.
Reverse for 'login' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Template error:
In template C:\pyprojects\cias\ciasproj\ciassite\templates\registration\password_reset_complete.html, error at line 5
Reverse for 'login' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: [] 1 : {% extends 'base.html' %}
2 :
3 : {% block content %}
4 : <p>
5 : Your password has been set. You may go ahead and sign in now.
6 : </p>
7 : {% endblock %}
register/password_reset_complete.html
{% extends 'base.html' %}
{% block content %}
<p>
Your password has been set. You may go ahead and sign in now.
</p>
{% endblock %}
accounts/urls.py --
urlpatterns = [
url(r"^signup/$", views.signup, name="account_signup"),
#url(r'^login/$', views.login, {'template_name': 'accounts/login.html'}, name='login'),
url(r'^login/', views.login_view, name='account_login'),
url(r'^logout/$', auth_views.logout, {'next_page': '/account/login'}, name='logout'),
url(r'^confirmemail/$', views.confirmemail, name='account_confirmemail'),
url(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',views.activate, name='activate'),
url(r'^activate/',views.activate, name='empty_activate'),
url(r'^password_reset/$', auth_views.password_reset, name='password_reset'),
url(r'^password_reset/done/$', auth_views.password_reset_done, name='password_reset_done'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,23})/$',
auth_views.password_reset_confirm, name='password_reset_confirm'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
auth_views.password_reset_confirm, name='password_reset_confirm'),
url(r'^reset/done/$', auth_views.password_reset_complete, name='password_reset_complete'),
]
I tried to modify the html link as
{% url reverse('account_login:login') %}
But that is giving another error --
Could not parse the remainder: '('account_login:login')' from 'reverse('account_login:login')'
Any help is highly appreciated. Thanks in advance.
I think it's a simple thing you are missing here. Whatever name you are giving there in the url list, you can use only that. If there is an app with a registered namespace, you have to use that.
In this case, you have defined the things directly and you should use the urls in that way only.
Instead of {% url 'login' %} it should be {% url 'account_login' %}.
Just the name you have given to url pattern.