Djangoチュートリアルの続き。
前回の記事はこちら。
Djangoには汎用ビューという、Web開発における基本的なビューを簡単に扱える機能が用意されている。
WordPressを例にとると、記事一覧ページ、記事詳細ページ、カテゴリや月別アーカイブページなどがあるが、Djangoの汎用ビューを使うとこれらと同様のビューを最低限のコード量で実装することができる。
今回は最新の質問5件を表示するindexページと、質問詳細detailページ、質問結果resultsページをそれぞれ汎用ビューに変換していく。
URLconfの修正
まずはpolls/urls.pyを以下のように修正する。
01 02 03 04 05 06 07 08 09 10 11 | from django.urls import path from . import views app_name = 'polls' urlpatterns = [ path(' ', views.IndexView.as_view(), name=' index'), path( '<int:pk>/' , views.DetailView.as_view(), name = 'detail' ), path( '<int:pk>/results/' , views.ResultsView.as_view(), name = 'results' ), path( '<int:question_id>/vote/' , views.vote, name = 'vote' ), ] |
ビューの修正
次にpolls/views.pyを修正する。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect from django.urls import reverse from django.views import generic from .models import Choice, Question class IndexView(generic.ListView): template_name = 'polls/index.html' context_object_name = 'latest_question_list' def get_queryset( self ): return Question.objects.order_by( '-pub_date' )[: 5 ] class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' class ResultsView(generic.DetailView): model = Question template_name = 'polls/results.html' |
IndexViewクラスにはListViewを、DetailViewとResultsViewにはDetailViewを使用している。
ListViewはオブジェクトのリスト表示を、DetailViewはオブジェクトの詳細ページの表示をそれぞれ担う。
少しだけコードを解説しておく。
まずはIndexViewクラスを見てみよう。
1 2 3 4 5 6 | class IndexView(generic.ListView): template_name = 'polls/index.html' context_object_name = 'latest_question_list' def get_queryset( self ): return Question.objects.order_by( '-pub_date' )[: 5 ] |
ListViewはデフォルトだと、app_name/model_name_list.htmlのテンプレートをレンダリングするようになっているが、template_name変数にファイルパスを指定することで任意のテンプレートを使うことができる。
context_object_nameにはテンプレートに渡すオブジェクト名を指定し、オブジェクト本体はget_querysetメソッドとして取得している。
次に、DetailViewとResultsViewだが、これらは処理としては全く同じことをしている。
1 2 3 4 5 6 7 | class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' class ResultsView(generic.DetailView): model = Question template_name = 'polls/results.html' |
テンプレートに渡すモデルとしてQuestionを指定し、template_nameにはそれぞれ用意したテンプレートファイルのパスを指定する。
これでWebにおける基本的な一覧ページと詳細ページを、Djangoの汎用ビューとして置き換えることができた。