django 1.7.8没有发送密码重置的电子邮件

时间:2022-11-15 13:13:50

Relevant part of urls.py for the project:

相关的url的一部分。py的项目:

from django.conf.urls import include, url, patterns
urlpatterns = patterns('',

  # other ones ...

  url(r'^accounts/password/reset/$', 
  'django.contrib.auth.views.password_reset',
 {'post_reset_redirect' : '/accounts/password/reset/done/'}),

  url(r'^accounts/password/reset/done/$', 
  'django.contrib.auth.views.password_reset_done'),

  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/'}),

  url(r'^accounts/password/done/$', 
  'django.contrib.auth.views.password_reset_complete'),

)

And by request, here's the password reset form:

根据要求,这是密码重置表单:

{% extends "site_base.html" %}

{% block title %}Reset Password{% endblock %}

{% block content %}
<p>Please specify your email address to receive instructions for resetting it.</p>

<form action="" method="post">
    <div style="display:none">
        <input type="hidden" value="{{ csrf_token }}" name="csrfmiddlewaretoken">
    </div>
     {{ form.email.errors }}
    <p><label for="id_email">E-mail address:</label> {{ form.email }} <input type="submit" value="Reset password" /></p>
</form>
{% endblock %}

But whenever I navigate to the /accounts/password/reset/ page and fill in email and click enter the page immediately redirects to /accounts/password/reset/done/ and no email is sent.

但是,每当我导航到/account /password/reset/ page并填写电子邮件并单击enter页面时,立即重定向到/accounts/password/reset/done/没有发送电子邮件。

My relevant settings.py variables:

我的相关设置。py变量:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'XXX@gmail.com'
EMAIL_HOST_PASSWORD = 'XXXXXX' 
EMAIL_PORT = 587

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER

And I know email works because my registration flow with django-registration-redux works flawlessly.

我知道电子邮件是有效的,因为我和django-registration-redux的注册流程完美无缺。

Any ideas?

什么好主意吗?

6 个解决方案

#1


13  

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. 邮件只发送给活动用户。没有用户的电子邮件将不会收到任何电子邮件(显然)。
  3. I got an error form's save method in line 270 for email = loader.render_to_string(email_template_name, c):
  4. 我在第270行有一个错误表单的保存方法,用于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: []

NoReverseMatch at /accounts/密码/reset/ Reverse for 'password_reset_confirm'带有参数'()'和关键字参数'{'token' ' ' ' ' ' ' ' ' 'uidb64': ' '没有找到' '。0模式(s)尝试:[]

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

好像你的网址。py不包含任何名为“password_reset_confirm”的url。所以你应该改变你的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.

PS:我已经测试了django 1.7.8,模板位于:Python34\Lib\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \注册。url和视图如您在问题中所写的那样使用。

#2


4  

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.

当你发布^账户/密码/重置/ $ django.contrib.auth.views。password_reset功能运行。这将使用默认的django. methods .forms。PasswordResetForm类来验证电子邮件。

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:

尝试在Django管理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()

#3


4  

Do you have email templates in your templates folder ?

您的模板文件夹中有电子邮件模板吗?

registration/password_reset_email.html
registration/password_reset_subject.txt

#4


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:

很有可能是表单clean方法失败了,你没有捕获错误。所以你只需要在不发送邮件的情况下得到重定向,并且不知道为什么。在clean()中抛出的任何验证错误都将显示在non_field_errors中。您需要添加{{form。将non_field_errors}插入页面以查看它们。试试这个:

<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>

#5


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.

我建议使用python调试器(一些IDE),并借助pdb (python调试器)对django.form.form.passwordresetform进行操作。保存并django.contrib.auth.views。password_reset查看什么不能工作。

#6


0  

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

domtes的答案帮我解决了这个问题,但我想强调一下这个潜在的原因:

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!

如果正在尝试重置的用户当前(重置之前)有一个无效的密码,Django将不会发送一个重置电子邮件!

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.

在我的例子中,我意外地在admin(自定义用户模型+ LastPass)中覆盖了密码字段,在此之后,一个用户不再重新设置。

#1


13  

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. 邮件只发送给活动用户。没有用户的电子邮件将不会收到任何电子邮件(显然)。
  3. I got an error form's save method in line 270 for email = loader.render_to_string(email_template_name, c):
  4. 我在第270行有一个错误表单的保存方法,用于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: []

NoReverseMatch at /accounts/密码/reset/ Reverse for 'password_reset_confirm'带有参数'()'和关键字参数'{'token' ' ' ' ' ' ' ' ' 'uidb64': ' '没有找到' '。0模式(s)尝试:[]

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

好像你的网址。py不包含任何名为“password_reset_confirm”的url。所以你应该改变你的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.

PS:我已经测试了django 1.7.8,模板位于:Python34\Lib\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \注册。url和视图如您在问题中所写的那样使用。

#2


4  

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.

当你发布^账户/密码/重置/ $ django.contrib.auth.views。password_reset功能运行。这将使用默认的django. methods .forms。PasswordResetForm类来验证电子邮件。

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:

尝试在Django管理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()

#3


4  

Do you have email templates in your templates folder ?

您的模板文件夹中有电子邮件模板吗?

registration/password_reset_email.html
registration/password_reset_subject.txt

#4


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:

很有可能是表单clean方法失败了,你没有捕获错误。所以你只需要在不发送邮件的情况下得到重定向,并且不知道为什么。在clean()中抛出的任何验证错误都将显示在non_field_errors中。您需要添加{{form。将non_field_errors}插入页面以查看它们。试试这个:

<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>

#5


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.

我建议使用python调试器(一些IDE),并借助pdb (python调试器)对django.form.form.passwordresetform进行操作。保存并django.contrib.auth.views。password_reset查看什么不能工作。

#6


0  

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

domtes的答案帮我解决了这个问题,但我想强调一下这个潜在的原因:

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!

如果正在尝试重置的用户当前(重置之前)有一个无效的密码,Django将不会发送一个重置电子邮件!

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.

在我的例子中,我意外地在admin(自定义用户模型+ LastPass)中覆盖了密码字段,在此之后,一个用户不再重新设置。