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

时间:2015-05-19 21:39:05

标签: python django email

项目urls.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'),

)

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

{% 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 %}

但每当我导航到/accounts/password/reset/页面并填写电子邮件并点击进入该页面时,会立即重定向到/accounts/password/reset/done/并且不会发送任何电子邮件。

我的相关settings.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

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

有什么想法吗?

7 个答案:

答案 0 :(得分:14)

我尝试重新创建你的情况,我遇到了以下情况:

  1. 邮件仅发送给活跃用户。与没有用户相关联的电子邮件将不会收到任何电子邮件(显然)。
  2. 我在email = loader.render_to_string(email_template_name, c)
  3. 的第270行中收到了错误表单的保存方法
      

    NoReverseMatch at / accounts / password / reset / Reverse for   带有参数'()'和关键字参数的'password_reset_confirm'   '{'token':'42h-4e68c02f920d69a82fbf','uidb64':b'Mg'}'找不到。 0   尝试过的模式:[]

    您的urls.py似乎不包含任何名为“password_reset_confirm”的网址。所以你应该改变你的网址:

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

    如果您完全设置了电子邮件配置,那么您应该收到没有问题的电子邮件。如果您仍然遇到此问题,请使用调试器检查其获取异常的位置。

    PS:我已经使用django 1.7.8进行了测试,模板位于:Python34\Lib\site-packages\django\contrib\admin\templates\registration。正如您在问题中所写的那样使用了网址和视图。

答案 1 :(得分:5)

当您向^accounts/password/reset/$发帖时,运行django.contrib.auth.views.password_reset功能。这将使用默认的django.contrib.auth.forms.PasswordResetForm类来验证电子邮件。

您应该注意到,只有与提供的电子邮件匹配的活跃用户才会收到电子邮件,并且只有在他们拥有可用密码的情况下才能发送电子邮件。

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

答案 2 :(得分:4)

您的templates文件夹中是否有电子邮件模板?

registration/password_reset_email.html
registration/password_reset_subject.txt

答案 3 :(得分:3)

好吧,最有可能是表单清理方法失败了,而且你没有捕获该错误。所以你只是在不发送邮件的情况下获得重定向,并且没有任何关于原因的线索。 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>

答案 4 :(得分:2)

我会检查垃圾邮件文件夹。因为有时某些电子邮件过滤器会严格处理带有链接的文本电子邮件。

我建议拿(带一些IDE)python调试器并在pdb(python调试器)的帮助下遍历django.contrib.auth.form.PasswordResetForm.save和django.contrib.auth.views.password_reset来查看是什么不行。

答案 5 :(得分:1)

answer by domtes为我解决了这个问题,但我想强调这个潜在原因:

如果您尝试重置的用户当前(重置前)无效密码,Django将默默地不发送重置电子邮件!

在我的情况下,我不小心覆盖了admin(自定义用户模型+ LastPass)中的密码字段,之后一个用户就没有重置了。

答案 6 :(得分:0)

对于Mac用户,尤其是如果您在常规iTerm旁边有Terminal,并且可能已在.bash_profile中的环境变量之前进行了设置,请在~/.zshrc上再次进行设置(如果您使用iTerm运行Django项目):

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

重新加载文件~/.zshrcsource ~/.zshrc,或直接关闭并再次打开iTerm

当然,以前,您已经打开了电子邮件设置中不太安全的选项。