ほとんどdjangoが仕組みを用意してくれてるんだけど、サンプルアプリを作って動かしてみたのでメモ
ドキュメントを読まずにやってるので、適当にやってエラー発生→直すの流れになっています
まずurls.pyにpassword_resetを定義
from django.contrib.auth.views import password_reset url(r'^password_reset/?$', password_reset, name='password_reset'),
アクセスするとエラー
NoReverseMatch at /password_reset Reverse for 'django.contrib.auth.views.password_reset_done' with arguments '()' and keyword arguments '{}' not found.
password_reset関数の以下の箇所でエラーになってるので
if post_reset_redirect is None: post_reset_redirect = reverse('django.contrib.auth.views.password_reset_done')
kwargsを渡してpost_reset_redirectを指定してやる
from django.contrib.auth.views import password_reset, password_reset_done from django.core.urlresolvers import reverse_lazy url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done')}, name='password_reset'), url(r'^password_reset_done/?$', password_reset_done, name='password_reset_done')
再びアクセスすると、今度はテンプレートがない
TemplateDoesNotExist at /password_reset registration/password_reset_form.html
template_nameもkwargsで指定して、
from django.contrib.auth.views import password_reset, password_reset_done from django.core.urlresolvers import reverse_lazy url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done'), 'template_name': 'apps/password_reset_form.html'}, name='password_reset'), url(r'^password_reset_done/?$', password_reset, name='password_reset_done')
適当にhtmlを作成
apps/password_reset_form.html
<h1>{% trans "Password reset" %}</h1> <p>{% trans "Forgotten your password? Enter your email address below, and we'll email instructions for setting a new one." %}</p> <form action="" method="post">{% csrf_token %} {{ form.email.errors }} <p><label for="id_email">{% trans 'Email address:' %}</label> {{ form.email }} <input type="submit" value="{% trans 'Reset my password' %}" /></p> </form>
画面が表示された
メールが飛ぶはずなので、メール設定をsettings.pyに追加する
settings.py
EMAIL_USE_TLS = True EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST_USER = 'hoge@gmail.com' # 使用するgmailアカウント EMAIL_HOST_PASSWORD = 'hoge' # 使用するgmailアカウントのパスワード EMAIL_PORT = 587
syncdbのときに作成したsuperuserのメールアドレスを入力すると以下のエラーに
メール本文のテンプレートのようです。
TemplateDoesNotExist at /password_reset registration/password_reset_email.html
email_template_nameでメール本文のテンプレートを指定して
url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done'), 'template_name': 'apps/password_reset_form.html', 'email_template_name': 'apps/password_reset_email.html'}, # 追加 name='password_reset'), url(r'^password_reset_done/?$', password_reset_done, name='password_reset_done')
djangoからパクってきてhtmlを用意
apps/password_reset_email.html
{% load i18n %}{% autoescape off %} {% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} {% trans "Please go to the following page and choose a new password:" %} {% block reset_link %} {{ protocol }}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb36=uid token=token %} {% endblock %} {% trans "Your username, in case you've forgotten:" %} {{ user.get_username }} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endautoescape %}
またurlエラーに
NoReverseMatch at /password_reset Reverse for 'django.contrib.auth.views.password_reset_confirm' with arguments '()' and keyword arguments '{u'uidb36': u'1', u'token': u'3gy-f8a8a25bf12e3d2d0641'}' not found.
password_reset_email.html内部でurl引いている箇所を修正
{% load i18n %}{% autoescape off %} {% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} {% trans "Please go to the following page and choose a new password:" %} {% block reset_link %} {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %} {# この行を修正 #} {% endblock %} {% trans "Your username, in case you've forgotten:" %} {{ user.get_username }} {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endautoescape %}
urls.pyにpassword_reset_confirmを追加
url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done'), 'template_name': 'apps/password_reset_form.html', 'email_template_name': 'apps/password_reset_email.html'}, name='password_reset'), url(r'^password_reset_done/?$', password_reset_done, name='password_reset_done'), url(r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', password_reset_confirm, name='password_reset_confirm')
メールは送信されたけどそのあとの遷移でエラー
TemplateDoesNotExist at /password_reset_done registration/password_reset_done.html
テンプレートパスを指定して、、
url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done'), 'template_name': 'apps/password_reset_form.html', 'email_template_name': 'apps/password_reset_email.html'}, name='password_reset'), url(r'^password_reset_done/?$', password_reset_done, {'template_name': 'apps/password_reset_done.html'}, # 修正 name='password_reset_done'), url(r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', password_reset_confirm, name='password_reset_confirm')
htmlを用意
apps/password_reset_done.html
{% load i18n %} {% block title %}{% trans 'Password reset successful' %}{% endblock %} {% block content %} <h1>{% trans 'Password reset successful' %}</h1> <p>{% trans "We've emailed you instructions for setting your password to the email address you submitted. You should be receiving it shortly." %}</p> {% endblock %}
パスワードリセット後の画面が表示されるようになりました
飛んできたメールはこんなのです
You're receiving this email because you requested a password reset for your user account at example.com. Please go to the following page and choose a new password: http://example.com/password_reset_confirm/1-3gy-f8a8a25bf12e3d2d0641/ Your username, in case you've forgotten: yuhei Thanks for using our site! The example.com team
ホスト名だけlocalhost:8000にかえてpassword_reset_confirにアクセスしたら次のエラーに
NoReverseMatch at /password_reset_confirm/1-3gy-f8a8a25bf12e3d2d0641/ Reverse for 'django.contrib.auth.views.password_reset_complete' with arguments '()' and keyword arguments '{}' not found.
またpost_reset_redirectをreverseで引こうとしてエラ−になってます。
password_reset_confirmでpost_reset_redirectを指定します
urls.py
url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done'), 'template_name': 'apps/password_reset_form.html', 'email_template_name': 'apps/password_reset_email.html'}, name='password_reset'), url(r'^password_reset_done/?$', password_reset_done, {'template_name': 'apps/password_reset_done.html'}, name='password_reset_done'), url(r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', password_reset_confirm, {'post_reset_redirect': reverse_lazy('password_reset_complete')}, # 修正 name='password_reset_confirm'), url(r'^password/reset/complete/$', password_reset_complete, name='password_reset_complete'),
テンプレートが無いエラー
TemplateDoesNotExist at /password_reset_confirm/1-3gy-f8a8a25bf12e3d2d0641/ registration/password_reset_confirm.html
password_reset_confirmのkwargsでテンプレートを指定して
url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done'), 'template_name': 'apps/password_reset_form.html', 'email_template_name': 'apps/password_reset_email.html'}, name='password_reset'), url(r'^password_reset_done/?$', password_reset_done, {'template_name': 'apps/password_reset_done.html'}, name='password_reset_done'), url(r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', password_reset_confirm, {'post_reset_redirect': reverse_lazy('password_reset_complete'), 'template_name': 'apps/password_reset_confirm.html'}, # 修正 name='password_reset_confirm'), url(r'^password/reset/complete/$', password_reset_complete, name='password_reset_complete'),
htmlを用意
apps/password_reset_confirm.html
{% load i18n %} {% if validlink %} <h1>{% trans 'Enter new password' %}</h1> <p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p> <form action="" method="post">{% csrf_token %} {{ form.new_password1.errors }} <p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p> {{ form.new_password2.errors }} <p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p> <p><input type="submit" value="{% trans 'Change my password' %}" /></p> </form> {% else %} <h1>{% trans 'Password reset unsuccessful' %}</h1> <p>{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p> {% endif %}
表示された
新しいパスワードを入力すると、そろそろ先回りしとけって感じだけどテンプレートエラーに
TemplateDoesNotExist at /password/reset/complete/ registration/password_reset_complete.html
urls.py
url(r'^password_reset/?$', password_reset, {'post_reset_redirect': reverse_lazy('password_reset_done'), 'template_name': 'apps/password_reset_form.html', 'email_template_name': 'apps/password_reset_email.html'}, name='password_reset'), url(r'^password_reset_done/?$', password_reset_done, {'template_name': 'apps/password_reset_done.html'}, name='password_reset_done'), url(r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', password_reset_confirm, {'post_reset_redirect': reverse_lazy('password_reset_complete'), 'template_name': 'apps/password_reset_confirm.html'}, name='password_reset_confirm'), url(r'^password/reset/complete/$', password_reset_complete, {'template_name': 'apps/password_reset_complete.html'}, # 修正 name='password_reset_complete'),
apps/password_reset_complete.html
{% load i18n %} <h1>{% trans 'Password reset complete' %}</h1> <p>{% trans "Your password has been set. You may go ahead and log in now." %}</p> <p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
完了ページも表示された。
これでpassword_resetできるようになった