Python Django 入門トップページ


Django によるコメント掲示板の開発:目次

  1. プロジェクトの作成
  2. Git でコミット
  3. Web サーバを起動しておく
  4. Config
  5. Comments アプリケーションを作る
  6. アプリケーションを有効にする
  7. はじめてのビューを作成する
  8. モデルを作る
  9. マイグレーション
  10. テストデータの設定
  11. データベースからコメント一覧を取得して表示してみよう
  12. Bootstrap の導入
  13. コメントの詳細表示
  14. urls.pyの書き方
  15. HTML のテンプレート化
  16. コメントの新規投稿
  17. コメントの編集機能を追加する
  18. さらにテンプレート化
  19. モデル,マイグレーションファイル,フォームの関連
  20. 入力内容の検証(バリデーション)
  21. コメントを削除する
  22. 一覧を逆順にする
  23. ページネーション
  24. フラッシュメッセージ
  25. Static コンテンツの設置
  26. 更新や削除にもフラッシュメッセージを表示
  27. テストの自動化を実現しよう
  28. デバッグツールバーを使う
  29. generic モジュールを使わずにコメント一覧を取得する
  30. コメント一覧のページネーション
  31. 一覧の表示順序を制御する
  32. generic モジュールを使わずにコメントの詳細を表示する
  33. コメント詳細にページ送り機能を作成する
  34. generic モジュールを使わずにコメント登録機能を作成する
  35. generic モジュールを使わずにコメント編集機能を作成する
  36. generic モジュールを使わずにコメント削除機能を作成する

Django によるコメント掲示板の開発

generic モジュールを使わずにコメント編集機能を作成する

コメントの編集機能も generic モジュールを使わずに作成してみましょう.すでに新規登録機能を generic モジュールを使わずに作っているので,編集機能も簡単に作成することができます.

まず,これまで同様,UpdateCommentView( ) クラスを削除するかコメントアウトします.その結果 from django.views.generic import UpdateView も不要になります.また,comments_update( ) 関数を定義します.この内容は comments_create( ) とほぼ同じで,異なる部分だけをハイライトしています.

comments/views.pyfrom django.urls import reverse_lazy
from django.urls import reverse
from django.shortcuts import render
from django.shortcuts import get_object_or_404
# from django.http import HttpResponse
# from django.views.generic import ListView
# from django.views.generic import DetailView
# from django.views.generic import CreateView
# from django.views.generic import UpdateView
from django.views.generic import DeleteView
from django.shortcuts import redirect
from django.contrib import messages
from .forms import CommentForm
from .models import Comment
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

# Create your views here.

...(中略)...

# class UpdateCommentView(UpdateView):
#     model = Comment
#     form_class = CommentForm
#     success_url = reverse_lazy('comments:index')

#     def get_context_data(self, **kwargs):
#         context = super().get_context_data(**kwargs)
#         context['page_title'] = 'コメントの更新'
#         context['form_name'] = 'コメントの更新'
#         context['button_label'] = 'コメントを更新する'
#         return context
#     def form_valid(self, form):
#         self.object = comment = form.save()
#         messages.success(self.request, 'コメントを更新しました')
#         return redirect(self.get_success_url())

def comments_update(request, comment_id):
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = get_object_or_404(Comment, pk=comment_id)
            comment.title = form.cleaned_data.get("title")
            comment.body = form.cleaned_data.get("body")
            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 = {}
        comment = get_object_or_404(Comment, pk=comment_id)
        context['form'] = CommentForm(
                            initial={
                                'title' : comment.title,
                                'body' : comment.body,
                            }
                        )
        context['page_title'] = 'コメントの編集'
        context['form_name'] = 'コメントの編集'
        context['button_label'] = 'コメントを更新する'
        return render(request, 'comments/form.html', context)

上の64行目で form.html を指定したので,comment_form.html ファイルを削除し,すでにある form.html を利用します.なお,内容に変更はありません.

comments/templates/comments/form.html{% extends 'base.html' %}

{% block title %}
{{ page_title }}
{% endblock %}

{% block content %}
<div class="container">
    <h1 class="my-5">{{ form_name }}</h1>
    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn btn-primary">{{ button_label }}</button>
    </form>
</div>
{% endblock content %}

最後にルートの定義を変更するために urls.py を編集します.

comments/urls.pyfrom django.urls import path

from . import views

app_name = 'comments'

urlpatterns = [
    path('', views.comments_index, name='index'),
    path('<int:comment_id>/', views.comments_show, name='show'),
    path('create/', views.comments_create, name='create'),
    path('<int:comment_id>/update/', views.comments_update, name='update'),
    path('<int:pk>/delete/', views.DeleteCommentView.as_view(), name='delete'),
]

Webサーバを起動してブラウザで動作を確認します.これまで同様に編集ができることを確認してください.

(py39) C:\Users\lecture\Documents\django\django_comment>python manage.py runserver ⏎
Watching for file changes with StatReloader
Performing system checks...

なお,上のviews.pyの46行目では次のように指定されているので,コメントの更新が成功した後はコメントの一覧ページにリダイレクトされます.

comments/views.pyreturn redirect(reverse('comments:index'))

もしも詳細ページにリダイレクトしたいのであれば,**kwargs という可変長引数を用いて次のように書くと良いでしょう.

comments/views.pyreturn redirect(reverse('comments:show', kwargs={'comment_id':comment_id}))

目次に戻る