Python Django 入門トップページ


ユーザ認証とコメント掲示板の開発

  1. プロジェクトの概要
  2. プロジェクトの作成と初期設定
  3. アプリケーションの作成と有効化
  4. ルートの記述
  5. ビューの定義
  6. HTML のテンプレート化
  7. HTML ファイルの作成
  8. Web ページ雛形の表示確認
  9. トップページの作成
  10. データベースのマイグレーション
  11. ユーザの作成
  12. ユーザ認証機能の実装
  13. セッション情報の確認
  14. ユーザ認証の状態を表示
  15. Navbar を設置
  16. モデルの作成とマイグレーション
  17. テストデータの投入
  18. コメントの一覧表示
  19. ページネーションと更新逆順表示
  20. コメント投稿機能の実装
  21. フラッシュメッセージ
  22. コメント詳細表示ページの実装
  23. 投稿者のユーザ名とメールアドレスの表示
  24. 投稿者であるかどうかの判断
  25. 編集・更新機能の実装
  26. コメント削除機能の実装
  27. Navbar の調整
  28. Profile の表示
  29. Profile の編集と更新
  30. パスワードの変更
  31. 管理サイトの準備
  32. 管理ユーザの登録
  33. 管理サイトへのログインとスタッフの登録
  34. グループの追加と権限の付与
  35. 管理サイトに comments アプリケーションを登録
  36. Comments アプリケーションから管理サイトへ

ユーザ認証とコメント掲示板の開発

パスワードの変更

次はユーザが自分自身のパスワードを変更できるような機能を作成しよう.Django にはパスワード変更のための仕組み (django.contrib.auth) が準備されているので,ここではその仕組を利用することにします.まずプロジェクトの urls.py を次の通り編集します.

django_comment_auth/urls.py
# from django.contrib import admin
from django.urls import include, path
from django_comment_auth import views
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('', views.index, name='index'),
    path('comments/', include('comments.urls')),
    path('accounts/', include('django.contrib.auth.urls')),
    path('accounts/password/', auth_views.PasswordChangeView.as_view(template_name='registration/password_form.html'), name='password_change_form'),
    path('accounts/password_change_done/', auth_views.PasswordChangeDoneView.as_view(template_name='registration/password_change_done.html'), name='password_change_done'),

    # path('admin/', admin.site.urls),
]

パスワード変更のためのページを comments/templates/registration 内に設置します.フォームは django.contrib.auth で定義されてものを使うことにします.

comments/templates/registration/password_form.html
{% extends "base.html" %}

{% block title %}
パスワード変更
{% endblock %}

{% block content %}
<h2>パスワード変更</h2>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-primary btn-block">パスワードを変更する</button>
</form>
{% endblock content %}

パスワードの変更が完了したあとにリダイレクトされるページを作成します.

comments/templates/registration/password_change_done.html
{% extends "base.html" %}

{% block title %}
パスワード変更完了
{% endblock %}

{% block content %}
<h2>パスワードを変更しました</h2>

<ul>
  <li>
    <a href="{% url 'comments:index' %}">コメント一覧</a>
  </li>
  <li>
    <a href="/">トップページへ</a>
  </li>
</ul>
{% endblock content %}

ログイン後の Navbar にパスワード変更のためのリンクを設置します.

comments/templates/base.html
{% load static %}<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{% block title %}{% endblock %}</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
</head>
<body>
<div class="container">
  <nav class="navbar navbar-expand-lg bg-light">
    <div class="container-fluid">
      <a class="navbar-brand" href="/">コメント</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="/comments/">Home</a>
          </li>
        </ul>
        {% if user.is_authenticated %}
          <ul class="navbar-nav ml-auto">
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                {{ user.username }}
              </a>
              <ul class="dropdown-menu">
                <li><a class="dropdown-item" href="{% url 'comments:profile' %}">Profile</a></li>
                <li><a class="dropdown-item" href="{% url 'password_change_form' %}">Change Password</a></li>
                <li><hr class="dropdown-divider"></li>
                <li><a class="dropdown-item" href="{% url 'comments:logout' %}">ログアウト</a></li>
              </ul>
            </li>
          </ul>
        {% else %}
          <ul class="navbar-nav ml-auto">
            <li class="nav-item">
              <a class="nav-link" href="{% url 'comments:index' %}">Login</a>
            </li>
          </ul>
        {% endif %}
      </div>
    </div>
  </nav>
  <div>
    {% for message in messages %}
      <p class="flash_message" onclick="this.classList.add('hidden')"> {{ message }}</p>
    {% endfor %}
  </div>
{% block content %}
{% endblock content %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
</body>
</html>

ログイン後の Navbar から Change Password をクリックします.

django2022-00116

パスワードの変更画面が表示されました.ここでパスワード変更を行います.このとき,2回入力する新しいパスワードが一致しない場合,新しいパスワードに「password」のような簡単な文字列を入力した場合,パスワードの文字列が短い場合,などでどのような動作になるかを確認してください.

django2022-00117

パスワードの変更に成功すると下のページにリダイレクトされます.一旦ログアウトして,新しいパスワードでログインできることも確認してください.

django2022-00118

Profile ページをもう一度開くと Password の値が変化していることがわかります.(本番システムでは Password を表示すべきでありません.)

django2022-00119

目次に戻る