我目前正在学习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.txt
和password_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
工作?
感谢您阅读此内容。