[Fixed]-Django 1.7.8 not sending emails with password reset

14👍

I tried to recreate your situation and I faced the following scenarios:

  1. Mail is only sent to active users. Email associated with no user will not get any email(obviously).
  2. I got an error form’s save method in line 270 for email = loader.render_to_string(email_template_name, c):

NoReverseMatch at /accounts/password/reset/ Reverse for
‘password_reset_confirm’ with arguments ‘()’ and keyword arguments
‘{‘token’: ’42h-4e68c02f920d69a82fbf’, ‘uidb64′: b’Mg’}’ not found. 0
pattern(s) tried: []

It seems that your urls.py doesn’t contain any url named ‘password_reset_confirm’. So you should change your url:

url(r'^accounts/password/reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
  'django.contrib.auth.views.password_reset_confirm',
 {'post_reset_redirect': '/accounts/password/done/'},),

To:

url(r'^accounts/password/reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
  'django.contrib.auth.views.password_reset_confirm',
 {'post_reset_redirect': '/accounts/password/done/'}, name='password_reset_confirm'),

If you have set your email configuration perfectly the you should get emails with no problem. If still you are facing this issue, please use a debugger to check where its getting exceptions.

PS: I have tested with django 1.7.8 and templates resides in: Python34\Lib\site-packages\django\contrib\admin\templates\registration. Urls and views are used as you have written in the question.

👤ruddra

5👍

When you POST to ^accounts/password/reset/$ the django.contrib.auth.views.password_reset function is run. This will use the default django.contrib.auth.forms.PasswordResetForm class to validate the email.

You should notice that an email is sent only to the active users matching the provided email, and only if they have a usable password.

Try to use the following function with the Django management shell:

from django.contrib.auth.models import get_user_model

def check_password_reset_cond(email):
     for u in get_user_model().objects.filter(email__iexact=email):
         assert u.is_active
         assert u.has_usable_password()
👤domtes

4👍

Do you have email templates in your templates folder ?

registration/password_reset_email.html
registration/password_reset_subject.txt

3👍

OK, it’s most likely something failing in the forms clean method, and you aren’t trapping that error. So you just get the redirect without sending the mail, and no clue as to why. Any validation error thrown in clean() will show up in non_field_errors. You need to add in {{form.non_field_errors}} into your page to see them. Try this:

<form method="post">{% csrf_token %}
    {{{form.non_field_errors}}
    {{ form.email.errors }}
<p><label for="id_email">E-mail address:</label> {{ form.email }} <input    type="submit" value="Reset password" /></p>
</form>

2👍

I would check spam folder for sure. Because sometimes some email filters treat text emails with links quite harshly.

I recommend take (some IDE with) python debugger and with a help of pdb (python debugger) walk over django.contrib.auth.form.PasswordResetForm.save and django.contrib.auth.views.password_reset to see what does not work.

👤yad

1👍

The answer by domtes solved this for me, but I wanted to put some emphasis on that potential cause:

If the user you’re trying to reset has currently (before the reset) an invalid password, Django will just silently not send a reset email!

In my case, I accidentally overwrote the password field in the admin (custom user model + LastPass), and after that the one user just didn’t reset anymore.

0👍

For mac users, especially if you have iTerm beside your normal Terminal, and probably you have set before your environment variable in .bash_profile, set them again on ~/.zshrc (if you run the Django project with iTerm):

export EMAIL_USER='email@gmail.com'
export EMAIL_PASS='password'

reload the file ~/.zshrc, source ~/.zshrc, or simply close and open the iTerm again.

Of course, previously, you have turned on the less secure option on your email setting.

👤A D

Leave a comment