クラスベースビューでの詳細画面の作成について
前回はクラスベースビューを使ってブログ記事の新規作成画面を作成した。
今回はクラスベースビューを使って詳細画面を作成する。
前回:【Django】クラスベースビューとforms.pyで新規作成画面を作成【ブログアプリ2】
現在のディレクトリ構成は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
デスクトップ └Blog2 ├app │ ├migrations │ ├__init__.py │ ├admin.py │ ├apps.py │ ├models.py │ ├tests.py │ ├views.py │ ├urls.py │ └forms.py ├db.sqlite3 ├config │ ├・・・ │ ├settings.py │ └urls.py ├templates │ ├base.html │ ├index.html │ ├list.html │ └create.html ├env_blog2 └manage.py |
クラスベースビューでの詳細画面を作成する手順
urls.pyの編集
~デスクトップ/Blog2/app/urls.py
1 2 3 4 5 6 7 8 9 10 11 |
from django.urls import path, include from .views import TopPageView1, TopPageView2, BlogListView, BlogCreateView, BlogDetailView #[1] app_name = 'blog' urlpatterns = [ path('', TopPageView1.as_view(), name="index1"), path('index/', TopPageView2.as_view(), name="index2"), path('list/', BlogListView.as_view(), name="list"), path('create/', BlogCreateView.as_view(), name="create"), path('detail/<int:pk>/', BlogDetailView.as_view(), name="detail"), #[2] ] |
[1]views.pyからBlogDetailViewをインポート
[2]新しいURLパターンを作成
利用者からのリクエストURLが以下と一致した場合に実行されるPath関数を追加した。
例
第一引数にある<int:pk>は、int型の引数pkを受け取ることを示している。
pkはprimary keyの略称。各ブログ記事のIDを指す。
第二引数でviews.pyのBlogDetailViewを.as_view()を使ってメソッドとして呼び出している。
第三引数ではこのURLパターンをdetailと名付けた。
views.pyの編集
~デスクトップ/Blog2/app/views.py
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 |
from django.shortcuts import render from django.views.generic import View, TemplateView, ListView, CreateView, DetailView #[1] from django.urls import reverse_lazy from .models import Blog from .forms import CreateForm # Create your views here. class TopPageView1(View): def get(self, request): template_name = 'index.html' return render(request, template_name) class TopPageView2(TemplateView): template_name = 'index.html' class BlogListView(ListView): model = Blog template_name = 'list.html' context_object_name = 'blogs' class BlogCreateView(CreateView): model = Blog form_class = CreateForm template_name = 'create.html' success_url = reverse_lazy('blog:list') #[2] class BlogDetailView(DetailView): model = Blog template_name = 'detail.html' content_object_name = 'blog' |
[1]DetailViewをインポート
DetailViewは汎用ビュークラス。
詳細画面を作成することに特化している。
[2]BlogDetailViewを作成
BlogDetailViewはDjangoの汎用ビュークラスであるDetailViewを継承している。
変数modelにBlogモデルを、template_nameにdetail.htmlのパスを、
DBからどの記事のデータを取得するかは、利用者がURLに含めてリクエストしてきたpk(ブログ記事のID)を、urls.pyで定義したpath関数から受け取って指定する。
detail.htmlの作成
~デスクトップ/Blog2/template/detail.html
1 2 3 4 5 6 7 8 |
{% extends 'base.html' %} {% block title %}{{ blog.title }}{% endblock %} {% block content %} <h1> {{ blog.title }} </h1> <p> {{ blog.content }} </p> {% endblock %} |
{% block title %}{{ blog.title }}{% endblock %}
blog.titleのblogは、views.pyのBlogDetailViewクラスでcontext_object_nameに格納したblogという文字列がdetail.htmlに渡されており、このblogがブログ記事のオブジェクトとして扱うことができている。
blog.titleのtitleはmodels.pyで定義したBlogモデルのフィールド。
blogオブジェクトはBlogモデルのインスタンスなので、その属性であるtitleとcontentを扱うことができる。
ここでは、詳細画面のタイトルをブログ記事のタイトルとした。
<p> {{ blog.content }} </p>
blog.titleと同様に、ブログ記事の内容をblogオブジェクトのcontent属性を使ってhtmlのpタグで囲って表示している。
ディレクトリ構成の確認
現在のディレクトリ構成は以下の通り。
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 |
デスクトップ └Blog2 ├app │ ├migrations │ ├__init__.py │ ├admin.py │ ├apps.py │ ├models.py │ ├tests.py │ ├views.py #編集 │ ├urls.py #編集 │ └forms.py ├db.sqlite3 ├config │ ├・・・ │ ├settings.py │ └urls.py ├templates │ ├base.html │ ├index.html │ ├list.html │ ├create.html │ └detail.html #新規作成 ├env_blog2 └manage.py |
urls.pyでは新しいURLパターンを作成した。
利用者からのリクエストのURLが以下と一致した場合に実行されるPath関数を追記している。
例
views.pyでは汎用ビュークラスのDetailViewを継承したBlogDetailViewを作成した。
detail.htmlではviews.pyのBlogDetailViewから受け取ったブログ記事の情報を表示している。
Django記事一覧
前回:【Django】クラスベースビューとforms.pyで新規作成画面を作成【ブログアプリ2】
次回:【Django】クラスベースビューで更新画面を作成【ブログアプリ2】
コメント