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 アプリケーションから管理サイトへ

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

フラッシュメッセージ

ここでは投稿完了時にフラッシュメッセージが表示されるようにします.

まず,views.py の comments_create() 関数の中で投稿完了時のフラッシュメッセージを作成します.

comments/views.py
from django.conf import settings
from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import redirect
from django.urls import reverse
from .models import Comment
from .forms import CommentForm
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib import messages

# Create your views here.

...(中略)...

def comments_create(request):
    if not request.user.is_authenticated:
        return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
    # context = {}
    # context['page_title'] = 'コメントの投稿'
    # return render(request, 'comments/form.html', context)
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = Comment()
            comment.title = form.cleaned_data.get("title")
            comment.body = form.cleaned_data.get("body")
            comment.owner_id = request.user.id
            comment.save()
            messages.success(request, '投稿しました')
            return redirect(reverse('comments:index'))
        else:
            # エラーメッセージをつけて返す
            context = {}
            context['page_title'] = 'コメントの投稿'
            context['form_name'] = 'コメントの投稿'
            context['button_label'] = 'コメントを投稿する'
            context['form'] = form
            return render(request, 'comments/form.html', context)
    else:
        context = {}
        context['form'] = CommentForm(
                            initial={
                                # 'title' : 'title',
                            }
                        )
        context['page_title'] = 'コメントの投稿'
        context['form_name'] = 'コメントの投稿'
        context['button_label'] = 'コメントを投稿する'
        return render(request, 'comments/form.html', context)

次にフラッシュメッセージを表示するための要素を HTML ファイルの中に埋め込みます.このとき,index.html などではなく base.html テンプレートに埋め込んでおけば,様々なシーンでフラッシュメッセージを活用することができるようになります.配置場所は 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="#">Navbar</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="#">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Link</a>
          </li>
          <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
              Dropdown
            </a>
            <ul class="dropdown-menu">
              <li><a class="dropdown-item" href="#">Action</a></li>
              <li><a class="dropdown-item" href="#">Another action</a></li>
              <li><hr class="dropdown-divider"></li>
              <li><a class="dropdown-item" href="#">Something else here</a></li>
            </ul>
          </li>
          <li class="nav-item">
            <a class="nav-link disabled">Disabled</a>
          </li>
        </ul>
        <form class="d-flex" role="search">
          <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
          <button class="btn btn-outline-success" type="submit">Search</button>
        </form>
      </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>

さらに,スタイルシートにフラッシュメッセージのスタイルを追加します.

comments/static/css/style.css
/* ログインフォームなどで行間を調整 */
.form-group {
    margin-bottom: 1.2rem;
}

/* ログインボタンなどの幅を広く */
.btn-block {
    width: 100%;
}

/* フラッシュメッセージ */
.flash_message {
    padding-top: 10px;
    padding-bottom: 10px;
    text-align: center;
    color: #ffc;
    background: #417690;
}

.hidden {
    display: none;
}
(py39) C:\Users\lecture\Documents\django\django_comment_auth>python manage.py runserver ⏎
Watching for file changes with StatReloader
Performing system checks...

Webサーバを再起動して動作を確認します.スタイルシートの再読み込みができない場合は Ctrl + F5 (ブラウザにより異なる場合があります)で強制再読み込みを行ってください.また,フラッシュメッセージをクリックすると hidden クラスが追加されるので非表示になることも確認してください.

django2022-00097

目次に戻る