用户密码重置:未将电子邮件发送到控制台

时间:2018-02-17 05:30:28

标签: django django-users

我目前正在学习Django,主要来自Andrew Pinkham的书"Django Unleashed",因为这本书是在Django 2之前的,所以我不能逐字使用这些代码,而是相应地调整代码。我现在在Ch。 21(扩展认证)。到目前为止一切正常,但我在用户重置密码时遇到问题。用户可以输入用于重置密码的电子邮件,并显示一条消息,说明电子邮件已成功发送 - 但控制台上没有显示任何内容(代码仍在DEBUG中,我还没有允许实际发送电子邮件,除了用于测试的控制台)。

以下是我项目结构的摘录:

pysawitweb
|_contact
|_pysawitweb
|  |_settings.py
|  |_urls.py
|  |_...
|_user
|  |_templates
|  |  |_user
|  |  |  |_base_user.html
|  |  |  |_logged_out.html
|  |  |  |_login.html
|  |  |  |_login_form.html
|  |  |  |_password_change_done.html
|  |  |  |_password_change_form.html
|  |  |  |_password_reset_complete.html
|  |  |  |_password_reset_confirm.html
|  |  |  |_password_reset_email.txt
|  |  |  |_password_reset_form.html
|  |  |  |_password_reset_sent.html
|  |  |  |_password_reset_subject.txt
|  |_urls.py
|  |_...
|_manage.py

settings.py文件中:

...
DEBUG = True

ALLOWED_HOSTS = []

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'contact',
    'weather',
    'organizer',
    'user',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'pysawitweb.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'django.template.context_processors.media',
            ],
        },
    },
]

WSGI_APPLICATION = 'pysawitweb.wsgi.application'

# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Email
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
SERVER_EMAIL = 'contact@django-unleashed.com'
DEFAULT_FROM_EMAIL = 'no-reply@django-unleashed.com'
EMAIL_SUBJECT_PREFIX = '[PySawit Web] '
MANAGERS = (
    ('Us', 'ourselves@django-unleashed.com'),
)


# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'en-us'

USE_I18N = True

USE_L10N = True

USE_TZ = True

TIME_ZONE = 'Asia/Kuala_Lumpur'


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]


# MEDIA
MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')


#LOGIN
LOGIN_REDIRECT_URL = reverse_lazy('organizer_opd_list')

LOGIN_URL = reverse_lazy('dj-auth:login')

LOGOUT_URL = reverse_lazy('dj-auth:logout')

一切正常:用户可以登录,注销和更改密码,但尝试重置密码无法向控制台发送电子邮件消息(不会出现错误)。我有一个contact应用程序(来自Django Unleashed书的第11章),它允许用户向我发送一封电子邮件 - 并且使用与上面settings.py文件中相同的设置完美地运行控制台上的电子邮件。

此处来自pysawitweb/urls.py

from user import urls as user_urls
...

urlpatterns = [
    ...
    path('user/', include(user_urls, namespace='dj-auth')),
]

user/urls.py

from django.contrib.auth import views as auth_views
from django.contrib.auth.forms import AuthenticationForm
from django.urls import include, path, reverse_lazy
from django.views.generic import RedirectView


password_urls = [
    path('',
         RedirectView.as_view(
             pattern_name='dj-auth:pw_reset_start',
             permanent=False)),

    path('change/',
         auth_views.password_change,
         {
             'template_name': 'user/password_change_form.html',
             'post_change_redirect': reverse_lazy('dj-auth:pw_change_done')
         },
         name='pw_change'),

    path('change/done/',
         auth_views.password_change_done,
         {
             'template_name': 'user/password_change_done.html'
         },
         name='pw_change_done'),

    path('reset/',
         auth_views.password_reset,
         {
             'template_name': 'user/password_reset_form.html',
             'email_template_name': 'user/password_reset_email.txt',
             'subject_template_name': 'user/password_reset_subject.txt',
             'post_reset_redirect': reverse_lazy('dj-auth:pw_reset_sent')
         },
         name='pw_reset_start'),

    path('reset/sent/',
         auth_views.password_reset_done,
         {
             'template_name': 'user/password_reset_sent.html'
         },
         name='pw_reset_sent'),

    path('reset/'
         '(<uidb64>[0-9A-Za-z_\-]+)/'
         '(<token>[0-9A-Za-z]{1,13}'
         '-[0-9A-Za-z]{1,20})/',
         auth_views.password_reset_confirm,
         {
             'template_name': 'user/password_reset_confirm.html',
             'post_reset_redirect': reverse_lazy('dj-auth:pw_reset_complete')
         },
         name='pw_reset_confirm'),

    path('reset/done/',
         auth_views.password_reset_complete,
         {
             'template_name': 'user/password_reset_complete.html',
             'extra_context': {'form': AuthenticationForm}
         },
         name='pw_reset_complete'),
]


app_name = 'user'


urlpatterns = [
    path('', RedirectView.as_view(pattern_name='dj-auth:login', permanent=False)),

    path('login/',
         auth_views.login,
         {
             'template_name': 'user/login.html'
         },
         name='login'),

    path('logout/',
         auth_views.logout,
         {
             'extra_context': {'form': AuthenticationForm},
             'template_name': 'user/logged_out.html'
         },
         name='logout'),

    path('password/', include(password_urls)),
]

user/login.html文件中,用户可以点击&#34;忘记密码?&#34;链接指示他们user/password_reset_form.html输入他们的电子邮件并提交。然后呈现user/password_reset_sent.html,告诉他们电子邮件已发送给他们 - 但控制台上没有任何内容(甚至是错误)。

user/login.html

{% extends parent_template|default:"user/base_user.html" %}

{% block title %}Login - {{ block.super }}{% endblock %}

{% block content %}
  {% include "user/login_form.html" %}
  <p><a href="{% url 'dj-auth:pw_reset_start' %}">Forgotten password?</a></p>
{% endblock %}

user/password_reset_form.html

{% extends parent_template|default:"user/base_user.html" %}

{% block title %}Reset Password - {{ block.super }}{% endblock %}

{% block content %}
  <p>Reset your password by email.</p>
  <form action="{% url 'dj-auth:pw_reset_start' %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Send Me Reset Instructions</button>
  </form>
{% endblock %}

最后,在user/password_reset_sent.html

{% extends parent_template|default:"user/base_user.html" %}

{% block title %}Password Reset Sent - {{ block.super }}{% endblock %}

{% block content %}
  <p>Password reset email sent!</p>
  <p>Please check your inbox and spam box.</p>
{% endblock %}

文本文件password_reset_email.txtpassword_reset_subject.txt分别如下:

Hello from {{ site_name }}!

We've received a request to reset {{ user.get_username }}'s password.

If you did not request a password reset, please ignore this message.

To reset your password, please navigate to:

{{ protocol }}://{{ domain }}{% url 'dj-auth:pw_reset_confirm' uid token %}

{{ site_name }} Password Reset

有人可以诊断问题,为什么没有电子邮件发送到控制台,虽然我的contact应用使用EMAIL_BACKEND中相同的setting.py工作?

感谢您阅读此内容。

1 个答案:

答案 0 :(得分:2)

解决了它。阅读the docs here表明Django只会向已注册电子邮件的用户发送电子邮件,这与联系人不同。 Sheesh ......