今回のテーマは「ユーザー情報変更画面を作成する」です。ここまでログイン、ログアウト、パスワード変更機能を見てきました。このままパスワードリセット機能を実装したいところですが、ユーザーにEmailを登録する必要がありますので、一度標準のビューから離れてユーザー情報変更画面を作成しましょう。
※本ページは「3-5. PasswordChangeViewを使用してパスワード変更画面を作成する」まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります
ユーザー情報変更画面のフォーム作成
まずはフォームを作成しましょう。accounts/forms.pyを作成します。
accounts/forms.py
from django.forms import ModelForm
from django.contrib.auth.models import User
class UserChangeForm(ModelForm):
class Meta:
model = User
fields = [
'email',
'last_name',
'first_name',
]
def __init__(self, email=None, first_name=None, last_name=None, *args, **kwargs):
kwargs.setdefault('label_suffix', '')
super().__init__(*args, **kwargs)
# ユーザーの更新前情報をフォームに挿入
if email:
self.fields['email'].widget.attrs['value'] = email
if first_name:
self.fields['first_name'].widget.attrs['value'] = first_name
if last_name:
self.fields['last_name'].widget.attrs['value'] = last_name
def update(self, user):
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
UserChangeFormのインスタンス生成時にユーザー情報を渡してフォームに予め表示するよう__init__関数をオーバーライドしています。また、ユーザー情報更新用の関数としてupdate関数を定義しています。このupdate関数はModelFormの関数ではないことに注意して下さい。
ユーザー情報変更画面のビュー作成
では次にビューを作成していきましょう。
accounts/views.py(一部抜粋)
from django.views.generic import FormView
class UserChangeView(LoginRequiredMixin, FormView):
template_name = 'registration/change.html'
form_class = UserChangeForm
success_url = reverse_lazy('accounts:profile')
def form_valid(self, form):
#formのupdateメソッドにログインユーザーを渡して更新
form.update(user=self.request.user)
return super().form_valid(form)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
# 更新前のユーザー情報をkwargsとして渡す
kwargs.update({
'email' : self.request.user.email,
'first_name' : self.request.user.first_name,
'last_name' : self.request.user.last_name,
})
return kwargs
普通のFormViewの使い方なので特段解説は不要かと思いますが、get_form_kwargs関数をオーバーライドしている部分に触れておきます。get_form_kwargs関数はdjango.views.generic.edit.FormMixinクラスの関数です。この関数が返すdict型オブジェクトがフォームクラス生成時にコンストラクタの実引数として投入されます。今回のケースですとUserChangeFormの__init__関数に渡されることになります。これにより現在のユーザー情報をフォームに表示することが可能となります。
get_form_kwargs関数をオーバーライドするとフォームにパラメータを渡すことができて便利なので覚えておくとフォームの使いみちが広がるかも知れません。
ユーザー情報変更画面のテンプレート作成
{% extends 'base/base.html' %}
{% block title %}ITについて切磋琢磨する掲示板 - {{ block.super }}{% endblock %}
{% block content %}
<div class="ui grid stackable">
<div class="eleven wide column">
<div class="ui breadcrumb">
<a href="{% url 'base:top' %}" class="section">TOP</a>
<i class="right angle icon divider"></i>
<a href="{% url 'accounts:profile' %}" class="section">プロフィール</a>
<i class="right angle icon divider"></i>
<div class="active section">ユーザー情報の変更</div>
</div>
<div class="ui segment">
<div class="content">
<div class="header"><h3>ユーザー情報の変更</h3></div>
<form class="ui form" action="" method="POST">
{% csrf_token %}
{{form.as_p}}
<button class="ui orange button" type="submit">確認</button>
</form>
</div>
</div>
<a href="{% url 'accounts:profile' %}">プロフィールに戻る</a>
</div>
{% include 'base/sidebar.html' %}
</div>
{% endblock %}
formを表示するだけなので、特段解説は不要だと思います。手を抜いてform.as_pで表示しています。
URLの設定
続いてURLの設定を行います。
accounts/urls.py(一部抜粋)
urlpatterns = [
# path('', include('django.contrib.auth.urls')),
path('create/', views.UserCreateView.as_view(), name="create"),
path('profile/', views.UserProfileView.as_view(), name="profile"),
+ path('change/', views.UserChangeView.as_view(), name="change"),
]
プロフィール画面のリンク修正
プロフィール画面のリンクも修正しておきましょう。
- <a class="ui button" href="">登録情報変更</a>
+ <a class="ui button" href="{% url 'accounts:change' %}">登録情報変更</a>
動作確認
では動作確認をしましょう。プロフィール画面から「登録情報変更」を押してユーザー情報変更画面に遷移して、フォームからユーザー情報を変更できればOKです。
最後に
では、次回はパスワードを忘れたユーザーのためのパスワードリセット画面について見ていきたいと思います。
Sponsored Link