概要
password_reset ページはDjango バージョン2 以降からViewクラスを利用するようになったのだがフィールドを追加する方法を簡潔に説明してくれるサイトが見つからなかったので記事にた。
この記事では PasswordResetForm に username
フィールドを追加する方法を案内する。
Class View については公式資料をみてね。
フォーム
Django 備え付けのpassword_reset ページには email フィールドしかないのでPasswordResetForm 継承して自分のフィールドを追加する。
PasswordResetForm のコードはここを参考。
from django import forms
from django.contrib.auth.forms import PasswordResetForm
class MyPasswordResetForm(PasswordResetForm):
username = forms.CharField(max_length=254)
field_order = ['username', 'email']
上記のようにPasswordResetForm クラスを継承して username フィールドを追加。
このように追加するとPasswordResetForm 内のフィールド(email)の次に追加フィールドが表示されるので field_order
を使って email は username の後に表示するよう定義する。
参考: field_orderについて.
ビュー
次にDjango が用意したpassword_reset 用のビューを継承する。
PasswordResetView のコードはここを参考.
from django.shortcuts import render, redirect
from django.contrib.auth import get_user_model
from django.contrib.auth.views import PasswordResetView
from .forms import MyPasswordResetForm
class MyPasswordResetView(PasswordResetView):
form_class = MyPasswordResetForm
def form_valid(self, form):
username = form.cleaned_data.get('username')
email = form.cleaned_data.get('email', '').lower()
try:
user = get_user_model().objects.get(username=username, email=email)
except(get_user_model().DoesNotExist):
user = None
if user is None:
return redirect('password_reset_done')
return super().form_valid(form)
form_class
をオーバーライドして継承したビューを指定する。
さらに form_valid
をオーバーライドしてusername の処理を追加する。
上記ではusername と emailを元にユーザーオブジェクトを取得している。
ユーザーが見つからなければリセットメールを送らずに ‘password_reset_done’ ページを表示して、見つかればリセットメールを送信する。
HTML テンプレート
特に追加で行う作業はなし。
デフォルトのパスを使用: templates\registration\password_reset_form.html
<form method="post">
{% csrf_token %}
{% for field in form %}
<div>
{{ field.label_tag }}
{{ field }}
{% if field.help_text %}<p>{{ field.help_text }}</p>{% endif %}
{% for error in field.errors %}<p>* {{ error|escape }}</p>{% endfor %}
</div>
{% endfor %}
<button type="submit">Submit</button>
</form>
URL
最後にMyPasswordResetView をurls に定義。
from django.urls import include, path
from . import views
urlpatterns = [
path('password_reset/', views.MyPasswordResetView.as_view(), name='password_reset'),
path('', include('django.contrib.auth.urls')), # first match, first served
]
結果
パスワードリセットページにフィールド追加完了!