もた日記

くだらないことを真面目にやる

Djangoメモ(32) : UpdateViewでユーザーアカウント情報を編集

Python 3.6.4 Django 2.0.2

A Complete Beginner's Guide to Djangoのチュートリアルを参考にユーザーアカウント情報を編集してみる。


UpdateViewでユーザーアカウント情報を編集

前回まででクラスベース汎用ビューのUpdateView, ListViewを使用してみたが、UpdateViewを使用してユーザーアカウント情報の編集機能を作成してみる。
accounts/views.pyを以下のように編集。

from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.views.generic import UpdateView

@method_decorator(login_required, name='dispatch')
class UserUpdateView(UpdateView):
    model = User
    fields = ('first_name', 'last_name', 'email')
    template_name = 'my_account.html'
    success_url = reverse_lazy('my_account')

    def get_object(self):
        return self.request.user
  • model : モデル名を指定。
  • fields : 編集するフィールド名を指定。
  • template_name : テンプレートファイル名を指定。
  • success_url : 正常に処理が完了した際のリダイレクト先。reverse_lazy()reverse()の遅延評価版で、URLConfがロードされる前にURLの逆引きをしたい時に使う。クラスベース汎用ビューではreverse_lazy()を使う。

myproject/urls.pyに下記行を追加。
クラスベースビューなのでaccounts_views.UserUpdateView.as_view()のようにする。

from django.conf.urls import url
from accounts import views as accounts_views

urlpatterns = [
    # ...
    path('settings/account/', accounts_views.UserUpdateView.as_view(), name='my_account'),
]

最後にtemplates/my_account.htmlテンプレートを作成。

{% extends 'base.html' %}

{% block title %}My account{% endblock %}

{% block breadcrumb %}
  <li class="breadcrumb-item active">My account</li>
{% endblock %}

{% block content %}
  <div class="row">
    <div class="col-lg-6 col-md-8 col-sm-10">
      <form method="post" novalidate>
        {% csrf_token %}
        {% include 'includes/form.html' %}
        <button type="submit" class="btn btn-success">Save changes</button>
      </form>
    </div>
  </div>
{% endblock %}

参考:includes/form.html(クリックで展開)

{% load form_tags widget_tweaks %}

{% if form.non_field_errors %}
  <div class="alert alert-danger" role="alert">
    {% for error in form.non_field_errors %}
      <p{% if forloop.last %} class="mb-0"{% endif %}>{{ error }}</p>
    {% endfor %}
  </div>
{% endif %}

{% for field in form %}
  <div class="form-group">
    {{ field.label_tag }}
    {% render_field field class=field|input_class %}
    {% for error in field.errors %}
      <div class="invalid-feedback">
        {{ error }}
      </div>
    {% endfor %}
    {% if field.help_text %}
      <small class="form-text text-muted">
        {{ field.help_text|safe }}
      </small>
    {% endif %}
  </div>
{% endfor %}


問題がなければ以下のフォームでユーザーアカウント情報が編集できるようになる。

f:id:wonder-wall:20180329212819p:plain


fieldsの変更

その他のUserモデルのフィールドを指定することもできる。

fields = ('username', 'first_name', 'last_name', 'email', 'is_superuser', 'is_staff')

f:id:wonder-wall:20180401142951p:plain

逆に限定することも可能。('email')だとtupleではなくstrになりエラーになるので注意。

fields = ('email', )

f:id:wonder-wall:20180401142938p:plain


まとめ

  • UpdateViewでユーザーアカウント情報を編集
  • fieldsで編集するフィールド名を指定
  • クラスベース汎用ビューではsuccess_urlreverse_lazy()を使う