3

Hey guys i keep getting this error while doing this feature on my web app for reseting passwords Idk why it happens Here is my urls.py code:

from django.urls import path
from .views import *
from django.contrib.auth import views as auth_views

Full traceback:

NoReverseMatch at /accounts/password_reset/
Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.
Request Method: POST
Request URL:    http://127.0.0.1:8000/accounts/password_reset/
Django Version: 3.1.6
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.
Exception Location: C:\Users\Dominique\Desktop\STUFF\dev\car_sales\env\lib\site-packages\django\urls\resolvers.py, line 685, in _reverse_with_prefix
Python Executable:  C:\Users\Dominique\Desktop\STUFF\dev\car_sales\env\Scripts\python.exe
Python Version: 3.8.5
Python Path:    
['C:\\Users\\Dominique\\Desktop\\STUFF\\dev\\car_sales\\src',
 'c:\\users\\dominique\\appdata\\local\\programs\\python\\python38-32\\python38.zip',
 'c:\\users\\dominique\\appdata\\local\\programs\\python\\python38-32\\DLLs',
 'c:\\users\\dominique\\appdata\\local\\programs\\python\\python38-32\\lib',
 'c:\\users\\dominique\\appdata\\local\\programs\\python\\python38-32',
 'C:\\Users\\Dominique\\Desktop\\STUFF\\dev\\car_sales\\env',
 'C:\\Users\\Dominique\\Desktop\\STUFF\\dev\\car_sales\\env\\lib\\site-packages']
Server time:    Sun, 28 Feb 2021 06:42:15 +0000

app_name = 'accounts'

urlpatterns = [
    path('create-user/', registerview, name='register'),
    path('login/', loginview, name='login'),
    path('logout/', logoutview, name='logout'),

    path('password_reset/', auth_views.PasswordResetView.as_view(template_name='accounts/reset_password.html'), name="password_reset"),
    path('password_reset_done/', auth_views.PasswordResetDoneView.as_view(template_name='accounts/reset_password_sent.html'), name="password_reset_done"),
    path('password_reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='accounts/reset_password_form.html'), name="password_reset_confirm"),
    path('password_reset_complete/', auth_views.PasswordResetCompleteView.as_view(template_name='accounts/reset_password_sucess.html'), name="password_reset_complete"),
]

and here is one of my templates that im using to override the default one reset_password.html:

<h2>Introduza o email para mudar a sua password</h2>

<form method="POST">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Enviar email de atualizacao de password">
</form>

Another error:

{% load i18n %}{% autoescape off %}
2   {% blocktranslate %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktranslate %}
3   
4   {% translate "Please go to the following page and choose a new password:" %}
5   {% block reset_link %}
6   {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
7   {% endblock %}
8   {% translate 'Your username, in case you’ve forgotten:' %} {{ user.get_username }}
9   
10  {% translate "Thanks for using our site!" %}
11  
12  {% blocktranslate %}The {{ site_name }} team{% endblocktranslate %}
13  
14  {% endautoescape %}

And idk why this happenssince im sending the uidb and the token in the url....

My SMTP conf for sending email with GMAIL:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'my_email'
EMAIL_HOST_PASSWORD = 'my_email_password'
filipe
  • 139
  • 2
  • 17

1 Answers1

2

The culprit is the app_name = 'accounts'. This means that the success_url that is defined in the PasswordResetView, which points to a view with the name password_reset_done thus no longer can find its view. The same will happen with the PasswordResetConfirmView.

You can override this with the name of the view that contains the namespace prefix:

from django.urls import path, reverse
from .views import *
from django.contrib.auth import views as auth_views

#    namespace &downarrow; (view names need to be prefixed with 'accounts:')
app_name = 'accounts'

urlpatterns = [
    path('create-user/', registerview, name='register'),
    path('login/', loginview, name='login'),
    path('logout/', logoutview, name='logout'),

    path(
        'password_reset/',
        auth_views.PasswordResetView.as_view(
            template_name='accounts/reset_password.html'
            success_url=reverse_lazy('accounts:password_reset_done')
        ),
        name='password_reset'
    ),
    path('password_reset_done/', auth_views.PasswordResetDoneView.as_view(template_name='accounts/reset_password_sent.html'), name='password_reset_done'),
    path(
        'password_reset/<uidb64>/<token>/',
        auth_views.PasswordResetConfirmView.as_view(
            template_name='accounts/reset_password_form.html'
            success_url=reverse_lazy('accounts:password_reset_complete')
        ),
        name='password_reset_confirm'
    ),
    path('password_reset_complete/', auth_views.PasswordResetCompleteView.as_view(template_name='accounts/reset_password_sucess.html'), name='password_reset_complete'),
]

In the template, you should also prefix it with the namespace, so:

{% url 'account:password_reset_confirm' uidb64=uid token=token %}

If this is the builtin template, you can create your own template, for example by copy pasting the original template [GitHub] and then save a new template and specify the path that that template with:

from django.urls import path, reverse
from .views import *
from django.contrib.auth import views as auth_views

#    namespace ↓ (view names need to be prefixed with 'accounts:')
app_name = 'accounts'

urlpatterns = [
    path('create-user/', registerview, name='register'),
    path('login/', loginview, name='login'),
    path('logout/', logoutview, name='logout'),

    path(
        'password_reset/',
        auth_views.PasswordResetView.as_view(
            template_name='accounts/reset_password.html',
            success_url=reverse_lazy('accounts:password_reset_done'),
            email_template_name='path_to/template.html'
        ),
        name='password_reset'
    ),
    path('password_reset_done/', auth_views.PasswordResetDoneView.as_view(template_name='accounts/reset_password_sent.html'), name='password_reset_done'),
    path(
        'password_reset/<uidb64>/<token>/',
        auth_views.PasswordResetConfirmView.as_view(
            template_name='accounts/reset_password_form.html'
            success_url=reverse_lazy('accounts:password_reset_complete')
        ),
        name='password_reset_confirm'
    ),
    path('password_reset_complete/', auth_views.PasswordResetCompleteView.as_view(template_name='accounts/reset_password_sucess.html'), name='password_reset_complete'),
]
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • ok, will try to do that and give you a feedbback, just one more thing, can you explain to me what is `reverse_lazy` and the `success_url` – filipe Feb 28 '21 at 07:20
  • @filipe: `reverse_lazy` determines the URL for a given view name, `success_url` is the URL to which the browser is redirected in case the form succeeds. – Willem Van Onsem Feb 28 '21 at 07:21
  • Noice! just a thing, now there is the same error idk why... i've putted above – filipe Feb 28 '21 at 07:32
  • @filipe: but did you rewrite the two `paths`, and with `accounts:` in the `reverse_lazy` part? – Willem Van Onsem Feb 28 '21 at 07:33
  • yea i inserted those 2 you indicated, Should i do that for all the urls paths? – filipe Feb 28 '21 at 07:35
  • @filipe: this is because the template contains a `{% url ... %}` that will require updating as well. – Willem Van Onsem Feb 28 '21 at 07:36
  • what should be the template that i need to add that pls? – filipe Feb 28 '21 at 07:39
  • @filipe: the one you are showing, that is likely the builtin, so will need to create your own and specify a path to that template, see edit. – Willem Van Onsem Feb 28 '21 at 07:49
  • and in the template that is used to put the `{% url ... %}` i just put inside this bit?`{% url 'account:password_reset_confirm' uidb64=uid token=token %}` – filipe Feb 28 '21 at 10:19
  • @filipe: yes. You should of course link the view to that template by setting the `email_template_name=...` parameter. – Willem Van Onsem Feb 28 '21 at 10:23
  • OHHH yea i see what you mean right now, kinda new to django, +/- 1.5/2months in this, and getting used to reading the docs! Now the error disapeared, and it goes to the `password_reset_done/` but doesnt send the email, all the credentials from the email are right and i ativated login with less secure apps on gmail, what could it be? – filipe Feb 28 '21 at 10:45
  • @filipe: by default the django email backend is simply something that writes it to the console. You will need to configure a real email backend. Can you see the email in the console where you are running the server? – Willem Van Onsem Feb 28 '21 at 10:48
  • @filipe: see https://docs.djangoproject.com/en/3.1/topics/email/#email-backends – Willem Van Onsem Feb 28 '21 at 10:49
  • yea i've read that bit of the docs, and you can see my SMTP conf in above code, idk whats wrong but the mail its not beeing – filipe Feb 28 '21 at 10:53
  • @filipe: did you already manage to send emails with this backend (so not per se to reset a password)? – Willem Van Onsem Feb 28 '21 at 10:56
  • @filipe: if you want to send emails through gmail, you will need to do some configure in GMail as well https://dev.to/abderrahmanemustapha/how-to-send-email-with-django-and-gmail-in-production-the-right-way-24ab – Willem Van Onsem Feb 28 '21 at 10:57
  • well, i tried what it says on that post, but it continues doing the same thing, doesnt send the email, very weird... – filipe Feb 28 '21 at 11:05
  • ok, i went and checked on gmail, there is a field wehre it says the last use of that app that i created and by the looks of it django didnt even reach that part of logging in, then it must be something wrong in the urls – filipe Feb 28 '21 at 11:08
  • 2
    i just realised what i was trying to do... i tought i had a user with a certain email..but i didnt so it wasnt sending nothing, but now when i used an email that was registred, it worked like a charm! so i am going to put your answer as the right one, because the errors i had they were all fixed, once again thank you for your pacience and time! – filipe Feb 28 '21 at 11:34