Django開発~ブログ構築編7~検索フォームの続きです。
本日は、ブログにレビュー機能をつけていきたいと思います。
Reviewモデルの追加
まずは、Reviewモデルをmodels.pyに追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
vi app/blog/models.py # new class Review(models.Model): post = models.ForeignKey( Post, on_delete=models.CASCADE, related_name='review') review = models.TextField(max_length=255) author = models.ForeignKey( CustomUser, on_delete=models.CASCADE) def __str__(self): return self.review |
このReviewは、Postモデルに対して、一対多で結びつくようにしました。
モデルを設定したので、マイグレーションを実行しましょう。
1 |
make migrate |
管理画面に追加
モデルを作成したら管理画面にも追加しておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
vi app/blog/admin.py from django.contrib import admin from .models import Post, Review # new @admin.register(Post) class PostAdmin(admin.ModelAdmin): list_display = ('title', 'slug', 'author', 'publish', 'status') list_filter = ('status', 'created', 'publish', 'author') search_fields = ('title', 'body') prepopulated_fields = {'slug': ('title',)} raw_id_fields = ('author',) date_hierarchy = 'publish' ordering = ('status', 'publish') # new @admin.register(Review) class PostAdmin(admin.ModelAdmin): list_display = ('post', 'review', 'author') list_filter = ('post', 'review', 'author') search_fields = ('post', 'review') raw_id_fields = ('author',) |
Form作成
続いては、Reviewフォームを作成しましょう。
1 2 3 4 5 6 7 8 9 10 11 |
vi app/blog/forms.py from django import forms from .models import Post, Review #new # new class ReviewForm(forms.ModelForm): class Meta: model = Review fields = ('review',) |
Review登録機能
views.pyにReviewの登録機能を実装します。
この機能は、投稿詳細画面に追加したいので、post_detail関数を修正しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
vi app/blog/views.py from django.contrib.auth import get_user_model from django.views.generic import CreateView, UpdateView, DeleteView from django.shortcuts import render, get_object_or_404, redirect from django_tables2 import RequestConfig from django.contrib.postgres.search import SearchVector from .models import Post from .forms import PostForm, SearchForm, ReviewForm # new from .tables import PostTable ... def post_detail(request, year, month, day, post): """Show post datail""" review_form = ReviewForm() post = get_object_or_404(Post, slug=post, status='published', publish__year=year, publish__month=month, publish__day=day) reviews = post.review.all() if request.POST: form = ReviewForm(request.POST) if form.is_valid(): f = form.save(commit=False) f.post = post f.author = request.user f.save() return render(request, 'blog/post/detail.html', { 'post': post, 'review_form': review_form, 'reviews': reviews,}) |
まず、「ReviewForm()」にて、フォームをインスタンス化しました。このインスタンスをdetail.html側で受け取り、フォームとして表示させます。
次に、「post.view.all()」にて、Postオブジェクトに紐づくReviewオブジェクトを取得します。投稿詳細画面にレビューを表示させる予定だからです。
最後にPOSTリクエスト時に、Reviewの内容をデータベースに登録する処理を行っています。
登録する際は、「commit=False」を指定したフォームオブジェクトを作成し、必要なプロパティを追加後に正式に「save()」で保存します。commmit=Falseを指定したオブジェクトを作成しておかないとデータの保存ができません。
投稿詳細画面の修正
投稿詳細画面に、Reviewフォームとレビュー一覧を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
vi app/blog/templates/blog/post/detail.html {% extends "blog/base.html" %} {% block title%}{{ post.title }}{% endblock %} {% block content %} <!-- Blog Detail --> <div> <p><a class="btn btn-outline-secondary btn-sm" href="{% url 'blog:post_list' %}">Back</a></p> <h1>{{ post.title }}</h1> <p class="date"> Published {{ post.publish }} by {{ post.author }} </p> {{ post.body|linebreaks }} </div> <!-- Reveiw Form --> <div> <h1 class="text-secondary m-2">REVIEW FORM</h1> <form action="." method="post"> {% csrf_token %} <div class="row"> <div class="col-12"> {{ review_form.review }} </div> <div class="col-12 mt-2"> <input type="submit" value="POST" class="btn btn-warning btn-lg btn-block"> </div> </div> </form> </div> <!-- Review List --> <div class="m-10"> <h1 class="text-secondary m-2">REVIEW</h1> {% for review in reviews %} <div class="card mb-3" style="width: 100%;"> <div class="card-body"> <div class="border-bottom"> {{ review.review|linebreaks }} </div> <div class="badge badge-pill badge-primary float-right mt-2"> Published {{ review.publish }} by {{ review.author }} </div> </div> </div> {% endfor %} </div> {% endblock %} |
動作確認
ブログ一覧からアクセスし、動作を確認してみましょう。「localhost:8000/blog」から投稿一覧を開き、そこから詳細画面に移動しましょう。

「REVIEW FORM」にメッセージを入力して「POST」ボタンを押下して下さい。


画像キャプチャのようにレビューが追加されたら成功です!
おわりに
Blogの実装に関しては、一通りの機能を作れたと思いますので、今回で最終回といたします^^
他にも色々な機能を作ることができると思いますので、ぜひ挑戦してみてください。(個人的には、デザインがダサいのでその辺を修正いただけると…)
長らくありがとうございました。
コメントを残す
コメントを投稿するにはログインしてください。