I am using Django 2.1 and getting an error during password reset authentication right at the end.
my urls
from django.conf.urls import url
from django.contrib import admin
from . import views
from django.contrib.auth import views as auth_views
from django.urls import reverse, reverse_lazy, resolve
app_name = 'partners'
urlpatterns = [
url(r'^$', views.home, name='partner_home'),
url(r'^(?P<partner_id>[0-9]+)/$', views.detail, name='detail'),
url(r'^login/$',auth_views.LoginView.as_view(template_name="partners/registration/login.html"), name="login"),
url(r'^logout/$',auth_views.LogoutView.as_view(template_name="partners/registration/logout.html"), name="logout"),
url(r'^register/$', views.register, name='register'),
url(r'^profile/$', views.view_profile, name='view_profile'),
url(r'^profile/edit/$', views.edit_profile, name='edit_profile'),
# Password URL's ###################################################################################################
url(r'^change-password/$', views.change_password, name='change_password'),
url(
r'^password_reset/$',
auth_views.PasswordResetView.as_view(
template_name="partners/registration/password_reset.html",
email_template_name="partners/registration/password_reset_email.html",
success_url=reverse_lazy("partners:password_reset_done"), # might be required
),
name='password_reset'
),
url(r'^password_reset_done/',
auth_views.PasswordResetDoneView.as_view(
template_name="registration/password_reset_done.html",
),
name='password_reset_done'
),
url(r'^password_reset_confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
# r'(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
auth_views.PasswordResetConfirmView.as_view(
template_name="registration/password_reset_confirm.html",
),
name='password_reset_confirm',
),
url(r'^password_reset_complete/$',
auth_views.PasswordResetCompleteView.as_view(
template_name="partners/registration/password_reset_complete.html",
),
name="password_reset_complete"
),
]
I am able to login, then go to the password reset view. An email is sent using the development server and I am able to use the link to create a new password. Once I enter the new password I get an error (but the password in the background is changed). I am not sure why this is the case at the moment .
I am not using my custom password_reset_xxx html file instead I am using the builtin views
My URLS and structure
The Error Message
You have put your password reset urls in the partners app, therefore you need to override the code wherever it reverses urls so that it uses the partners namespace.
In this case, you need to override success_url in PasswordResetConfirmView.
auth_views.PasswordResetConfirmView.as_view(
template_name="registration/password_reset_confirm.html",
success_url = reverse_lazy('partners:password_reset_complete')
),
However, you may find there are other places that you need to override to get the password reset working. As I suggested on your other question, it would be simpler to move the password reset URLs out of the partners app.
Related
I am new to Django. I'm trying to implement jet authentication along with social authentication.
I'm following this tutorial https://jkaylight.medium.com/django-rest-framework-authentication-with-dj-rest-auth-4d5e606cde4d
I tried to implement the same but its not working.
I'm getting this error:
django.urls.exceptions.NoReverseMatch: Reverse for 'account_confirm_email' not found. 'account_confirm_email' is not a valid view function or pattern name.
My project level urls.py
from drf_spectacular.views import (
SpectacularAPIView,
SpectacularSwaggerView
)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
# path('account/', include('allauth.urls')),
path('admin/', admin.site.urls),
path('api/user/', include('user.urls')),
path('api/schema/', SpectacularAPIView.as_view(), name='api-schema'),
path(
'api/docs/',
SpectacularSwaggerView.as_view(url_name='api-schema'),
name='api-docs'
),
]
My App level urls.py
from django.urls import path, re_path
from dj_rest_auth.registration.views import RegisterView, VerifyEmailView, ConfirmEmailView
from dj_rest_auth.views import LoginView, LogoutView
from user import views
app_name = 'user'
urlpatterns = [
path('account-confirm-email/<str:key>/', ConfirmEmailView.as_view()),
path('register/', RegisterView.as_view()),
path('login/', LoginView.as_view()),
path('logout/', LogoutView.as_view()),
path('verify-email/',
VerifyEmailView.as_view(), name='rest_verify_email'),
path('account-confirm-email/',
VerifyEmailView.as_view(), name='account_email_verification_sent'),
re_path(r'^account-confirm-email/(?P<key>[-:\w]+)/$',
VerifyEmailView.as_view(), name='account_confirm_email'),
path('listusers/', views.ListUsers.as_view(), name='list-users'),
]
When I try to register a user. It causes this error.
I'm using dj-rest-auth package to implement authentication.
If I replace the email verification related urls from app level to project level. Then everything is working fine.
What is causing this error ?
For the registration part, you have to use allauth which has some baked-in integrations with dj-rest-auth
also, you would have to add some things in your settings.py:
INSTALLED_APPS = [
"dj_rest_auth.registration",
"allauth",
"allauth.account"
]
AUTHENTICATION_BACKENDS = [
"allauth.account.auth_backends.AuthenticationBackend",
"django.contrib.auth.backends.ModelBackend",
]
add these URLs to the urls.py:
urlpatterns = [
path("signup/", include("dj_rest_auth.registration.urls"))
path("verify-email/", VerifyEmailView.as_view(), name="rest_verify_email"),
path(
"account-confirm-email/",
VerifyEmailView.as_view(),
name="account_confirm_email_sent",
),
path(
"account-confirm-email/<key>/",
VerifyEmailView.as_view(),
name="account_confirm_email",
),
]
The request is not getting <str:key>. Please check where you are supplying. It can be from view or template.
I am using Django's default password reset views and forms to send an email to the user for them to reset their password via a link in the email. I have most of the development complete but am stuck on one issue. When I receive the email from the local host, I click the link, enter my new password 2 times, hit 'submit' and get this error: Error Message.
Below is my code.
urls.py
"""defines URL patterns for users"""
from django.urls import path, include, reverse_lazy
from django.contrib.auth import views as auth_views
from . import views
app_name = 'users'
urlpatterns = [
# include all default auth urls
path('', include('django.contrib.auth.urls')),
path('register/', views.register, name='register'),
path(
'reset_password/',
auth_views.PasswordResetView.as_view(
template_name='registration/password_reset.html',
success_url=reverse_lazy('users:password_reset_done')
) ,
name='reset_password'
),
path(
'reset/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(
template_name='registration/password_reset_form.html',
success_url=reverse_lazy('users:password_reset_complete')
),
name='password_reset_confirm'
),
path(
'password_reset_done/',
auth_views.PasswordResetDoneView.as_view(
template_name="registration/password_reset_sent.html"),
name='password_reset_done'
),
path(
'password_reset_complete/',
auth_views.PasswordResetCompleteView.as_view(
template_name='registration/password_reset_done.html'),
name='password_reset_complete'
),
path('forgot_username/', views.forgot_username, name="forgot_username"),
path('username_retrieval/', views.username_retrieval, name="username_retrieval"),
]
As you can see, I am using the namespace 'users' in the success_url variable, however, it seems to work on the reset_password path, but it does not seem to work on the reset/<uidb64>/<token> path.
One thing to be aware of is that I have a custom user model in my application. Would that affect my ability to use this default Django password reset method?
In addition, here are my templates under the users/templates/registration/ folder: User App Templates
Some other things to mention:
When I click on the link from my email, I am directed to password_reset_confirm and not password_reset_form so that tells me that the template name is not being overwritten as well.
When I change
success_url=reverse_lazy('users:password_reset_complete')
to
success_url=reverse_lazy('users:password_reset_completed')
the app doesn't look for users:password_reset_completed so that implies that the success_url is not being overwritten.
Any help would be appreciated and I can post more code and answer questions if necessary.
Thanks in advance!
this line is overwriting all your paths:
path('', include('django.contrib.auth.urls')),
just remove it or if you want to keep some of them place it at the end after your paths
I have been building a user account functionality for a Django app. In doing so, I have come across a problem and am uncertain of whether I am doing something wrong or have encountered an unfamiliar quirk of Django/Python. Any help is appreciated.
I have the following set of (working) urls (user_accounts/urls.py):
app_name = 'user_accounts'
urlpatterns = [
path('signup', views.UserSignUpView.as_view(), name='signup'),
path('logout', auth_views.LogoutView.as_view(), name='logout'),
path('login', auth_views.LoginView.as_view(template_name='user_accounts/login.html'), name='login'),
re_path(r'^reset/$', auth_views.PasswordResetView.as_view(template_name='user_accounts/password_reset.html', email_template_name='user_accounts/password_reset_email.html', subject_template_name='user_accounts/password_reset_subject.txt'), name='password_reset'),
re_path(r'^reset/done/$', auth_views.PasswordResetDoneView.as_view(template_name='user_accounts/password_reset_done.html'), name='password_reset_done'),
re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html'), name='password_reset_confirm'),
re_path(r'^reset/complete/$', auth_views.PasswordResetCompleteView.as_view(template_name='user_accounts/password_reset_complete.html'), name='password_reset_complete')
]
I have been trying to test it as follows (user_accounts/tests/test_views_forms.py):
class SuccessfulPasswordResetTests(TestCase):
def setUp(self):
email = 'jon#doe.com'
User.objects.create_user(username='john', email=email, password='123abcdef')
url = reverse('user_accounts:password_reset')
print(reverse('user_accounts:password_reset_done'))
self.response = self.client.post(url, {'email': email})
def test_redirection(self):
'''
A valid form submission should redirect to password_reset_done
'''
url = reverse('password_reset_done')
self.assertRedirects(self.response, url)
The issue is that I get the following error:
File
"/home/user-name/sites/project-web/project/user_accounts/tests/test_views_forms.py",
line 128, in setUp
self.response = self.client.post(url, {'email': email})
django.urls.exceptions.NoReverseMatch: Reverse for
'password_reset_done' not found. 'password_reset_done' is not a valid
view function or pattern name.
Yet, when I navigate directly to /user/reset/done/ in the browser, it serves the proper template.
The project's urls.py file looks as follows. Please note that I am using DjangoCMS
from django.contrib import admin
from django.urls import include, path
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('video/', include('video_uploader.urls')),
path('user/', include('user_accounts.urls')),
path('', include('cms.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
You just need to set the success_url attribute in the PasswordResetView. Out of the box it defaults to reverse_lazy('password_reset_done') but since you're using a custom app name the url can't be resolved even though the namespace is the same.
This should do the trick:
re_path(r'^reset/$', auth_views.PasswordResetView.as_view(
template_name='user_accounts/password_reset.html',
success_url=reverse_lazy('user_accounts:password_reset_done'),
email_template_name='user_accounts/password_reset_email.html',
subject_template_name='user_accounts/password_reset_subject.txt'), name='password_reset')
This is a working code. Note the addition of success_url in several paths, which end up working as a cascade. That is one gets triggered after another. I also converted from the regex format to the path format. This may have been needed to get the thing working as well.
from django.urls import path, re_path, reverse_lazy, include
from django.contrib.auth import views as auth_views
from . import views
app_name = 'user_accounts'
urlpatterns = [
path('signup/', views.UserSignUpView.as_view(), name='signup'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('login/', auth_views.LoginView.as_view(template_name='user_accounts/login.html'), name='login'),
path('password-change/', auth_views.PasswordResetView.as_view(template_name='user_accounts/password_reset.html', email_template_name='user_accounts/password_reset_email.html', subject_template_name='user_accounts/password_reset_subject.txt', success_url = reverse_lazy('user_accounts:password_reset_done')), name='password_reset'),
path('password-change/done/', auth_views.PasswordResetDoneView.as_view(template_name='user_accounts/password_reset_done.html'), name='password_reset_done'),
#re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html'), name='password_reset_confirm'),
path('password-change/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='user_accounts/password_reset_confirm.html', success_url = reverse_lazy('user_accounts:password_reset_complete')), name='password_reset_confirm'),
path('password-change/complete/', auth_views.PasswordResetCompleteView.as_view(template_name='user_accounts/password_reset_complete.html'), name='password_reset_complete')
]
I have a problem with django's view "password_reset_done".
When I try to open accounts/reset-password I have this error.
But if I open url accounts/reset-password/done it works.
URLS.PY of "accounts" app
from django.conf.urls import url
from django.contrib.auth.views import login , logout, password_reset,
password_reset_done
from . import views
urlpatterns = [
url(r'^register/$', views.register, name='register'),
url(r'^profile/$', views.profile, name='profile'),
url(r'^profile/prpage/(\d+)/$', views.profile, name='prpage'),
url(r'^profile-edit/$', views.profiledit, name='profile-edit'),
url(r'^login/$', login ,{'template_name':'accounts/login.html'},
name='login'),
url(r'^logout/$', views.logout_view, name='logout'),
url(r'^profile/(?P<proj_id>\d+)/$', views.userprojectpage,
name='userprojectpage'),
url(r'^changepassword/$', views.changepassword, name='changepassword'),
url(r'^reset-password/$', password_reset, name='reset_password'),
url(r'^reset-password/done/$', password_reset_done,
name='password_reset_done'),
]
please help! Thanks in advance)
Add success_url parameter of Class Based View PasswordResetView. This will replace default route of password_reset_done
from django.urls import path, re_path, include, reverse_lazy
path('reset/',PasswordResetView.as_view(
template_name='password_reset.html',
email_template_name='password_reset_email.html',
subject_template_name='password_reset_subject.txt',
...
success_url = reverse_lazy('accounts:password_reset_done')
...
...
),name='password_reset'),
11 there are some change made look like password_reset, password_reset_done not able to import therefore display this error regarding this url https://github.com/django/django/blob/stable/1.11.x/django/contrib/auth/views.py.
There are two way to resolve the error above.
to resolve this error add url(r'', include('django.contrib.auth.urls')), to main urls.py in your project. This will stopped the error and keep your urls in your accounts:
url(r'^reset-password/$', password_reset, name='reset_password'),
url(r'^reset-password/done/$', password_reset_done,
name='password_reset_done'),
I have resolved this error like above and it works fine.
Second way to resolve the error is different than first option above,remove the url(r'', include('django.contrib.auth.urls')), from main urls.py file and in your accounts/urls.py add following url's:
url(r'^reset-password/$', password_reset,
{'template_name':'reset_password.html',
'post_reset_redirect':'accounts:password_reset_done',
'email_template_name': 'reset_password_email.html'},
name='reset_password'),
url(r'^reset-password/done/$', password_reset_done,
{'template_name': 'reset_password_done.html'}, name='password_reset_done'),
url(r'^reset-password/confirm/(?P[0-9A-Za-z]+)-(?P.+)/$',
password_reset_confirm, {'template_name': 'reset_password_confirm.html',
'post_reset_redirect':'accounts:password_reset_complete'},
name='password_reset_confirm'),
This is the second solution and working.
I hope that helps your problem and sorry for delay respond your last comment, I was away.
DilMac
I have a blog made in django in a VPS. The blog is working fine but to access it I have to write the url example.com/blog/
What I'm trying is to make an automatic redirection so when a user enters example.com/ it automatically redirects to example.com/blog/
The project is set under apache.
This is my the configuration in myproject/urls.py:
urlpatterns = [
url(r'^blog/', include('blog.urls', namespace="blog")),
url(r'^admin/', include(admin.site.urls)),
]
This is the configuration of myproject/blog/urls.py that right now is formed by a post list and a post detail:
urlpatterns = patterns('',
# Index
url(r'^(?P<page>\d+)?/?$', ListView.as_view(
model=Post,
paginate_by=5,
),
name='index'
),
# Individual posts
url(r'^(?P<pub_date__year>\d{4})/(?P<slug>[a-zA-Z0-9-]+)/?$', DetailView.as_view(
model=Post,
),
name='post'
),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I already tried to add a .htaccess with different configurations but it's not working.
Is there a way to redirect from django?
If you're sure that you want that / to redirect to /blog/ for that you can create a temporary index view and redirect the response to /blog/
url(r'^', temp_index, name='index'),
def temp_index(request):
return HttpResponseRedirect('/blog/')
If you want that / must show /blog then replace
url(r'^blog/', include('blog.urls', namespace="blog")), with
url(r'^', include('blog.urls', namespace="blog")),