その4
記事に対してコメントを表示させましょう。
commentはmodels.pyでDBを持ちますが、コメント入力フォームはforms.pyで作ります。
modelとformの違いはこちら、
Djangoにおけるforms.pyとmodels.pyの違い
modelsはDBに対応するものですが、formsは入力画面に対応するものです。
modelsとformsを連携させたり、modelからformを作ることはありますが、 両者は別の責任を担います。
ふむ。
では早速。
models.py
追加する。
class Comment(models.Model):
post = models.ForeignKey('Post', on_delete=models.CASCADE)
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
name = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
class Meta:
ordering = ['-created_date']
'Post', on_delete=models.CASCADE
とは、Postが削除された時に、Commentも一緒に削除するということである。
DB更新
python manage.py makemigrations blog
python manage.py migrate blog
forms.py
ないので、新規作成します。
これは、コメント入力フォームからmodels.pyのCommentに繋げています。
from django import forms
from . import models
class CommentForm(forms.ModelForm):
class Meta:
model = models.Comment
fields = ('name', 'text',)
views.py
以下のように、def article
の中身を書き換えます。
(略)
from .models import Post, Comment #Comment追加
from . import forms #この行追加
(略)
def article(request, pk):
article = Post.objects.get(id=pk)
comments = Comment.objects.filter(post=article)
if request.method == "POST": #入力フォームはPOSTなので
form = forms.CommentForm(request.POST)
if form.is_valid(): #もし、formの内容が正しい時は
comment = form.save(commit=False) #formの内容はまだセーブしません!
comment.post = article
comment.author = request.user
comment.save() #ユーザーを追加したのちにセーブ
else:
form = forms.CommentForm()
print(article)
return render(request, 'blog/article.html', {
'article': article
'form': form,
'comments': comments
}) #form と comment を追加
return renderの中身も、form
とcomment
を追加しておきます。
urls.py
コメントは、article.html内に表記されるので、url自体は変わりません。
ここの変更はナシです。
article.html
記事の下のところにこのような記述を追加します。
<div>
<h3>コメント</h3>
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
<hr>
{% for comment in comments %}
author: {{ comment.author }}<br>
name: {{ comment.name }}<br>
{{ comment.text }}<br>
<hr>
{% endfor %}
</div>
入力フォームは<form method="POST" action=""></form>
で括ります。
POSTは情報を送る方なので、セキュリティのために(クロスサイトリクエストフォージェリ(CSRF) を防ぐために)
{% csrf_token %}
というものを入れます。
また、{{form}}だけでもよいのですが、各コンテンツを
タグで括る場合
{{form.as_p}}
とします。pじゃなくても大丈夫です。
admin.py
最後にコメントのあれやこれやも管理ページから行えるようにするのであれば、
from django.contrib import admin
from .models import Post, Comment #Comment追加
admin.site.register(Post)
admin.site.register(Comment) #この行追加
しておくと、localhost:8000/adminからCommentsが見られるようになります!