3-6. ユーザー情報変更画面を作成する

今回のテーマは「ユーザー情報変更画面を作成する」です。ここまでログイン、ログアウト、パスワード変更機能を見てきました。このままパスワードリセット機能を実装したいところですが、ユーザーに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


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です