次は,コメントの投稿機能の作成に取り掛かろう.まずは,コメントの新規投稿画面と更新画面で共通するフォームの部品(title と body の入力ボックス)を設計する.このために,comments/forms.py を新規に作成する.
comments/forms.py
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('title', 'body')
widgets = {
'title': forms.TextInput(attrs={
'class': 'form-control'
}),
'body': forms.TextInput(attrs={
'class': 'form-control'
}),
}
labels = {
'title': 'タイトル',
'body': '本文',
}
views.py (まだコードを入力していない)からは モデル名_form.py
が呼び出されるので,commment_form.py
を作成し,フォームの中に投稿ボタンを設置し,フォームの中にいま作成した fomrs.py を入れる(8行目)ようにする.
comments/templates/comments/comment_form.html
{% extends 'base.html' %}
{% block title %}
コメント投稿
{% endblock %}
{% block content %}
<div class="container">
<h1 class="my-5">投稿フォーム</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">コメントを投稿する</button>
</form>
</div>
{% endblock content %}
views.py に CreateCommentView クラスを設置する.なお,15行目は投稿が成功したときに,comments アプリケーションの index という名前のルートにリダイレクトするという意味である.これはつまり,comments/urls.py の 7行目で name='index'
と定義されたトップページへとリダイレクトすることを意味している.
comments/views.py
from django.urls import reverse_lazy
from django.views.generic import ListView
from django.views.generic import DetailView
from django.views.generic import CreateView
from .forms import CommentForm
from .models import Comment
... (中略) ...
class ShowCommentView(DetailView):
model = Comment
class CreateCommentView(CreateView):
model = Comment
form_class = CommentForm
success_url = reverse_lazy('comments:index')
最後に,ルートを記述する.
comments/urls.py
from django.urls import path
from . import views
app_name = 'comments'
urlpatterns = [
path('', views.CommentIndexView.as_view(), name='index'),
path('<int:pk>/', views.ShowCommentView.as_view(), name='show'),
path('create/', views.CreateCommentView.as_view(), name='create'),
]
この作業によって,http://127.0.0.1:8000/create/ から新規にコメントを投稿できるようになった.
投稿が成功すれば,下図のトップページにリダイレクトされ,そのページの最下部に投稿した内容が表示されていることが確認できる.
投稿ができるようになったので,コメント一覧のページから投稿ページにリンクを張っておく.
comments/templates/comments/comment_list.html (抜粋)
{% extends "base.html" %}
{% block title %}
コメント一覧
{% endblock %}
{% block content %}
<div class="container">
<h1 class="my-5">コメント一覧</h1>
{% for comment in object_list %}
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">
<a href="{% url 'comments:show' comment.id %}">
{{ comment.title }}
</a>
</h5>
<p class="card-text">{{ comment.body }}</p>
</div>
</div>
{% endfor %}
<hr>
<div>
<p>
<a href="{% url 'comments:create' %}">
新規コメントの投稿
</a>
</p>
</div>
</div>
{% endblock content %}