views.py を(PyQにおいても)これまでは関数を用いて記述してきたものの、
汎用ビューを継承してクラス定義を行うことで、よりコンパクトな記述が可能となる。
polls/urls.py
from django.urls import path
from . import views
app_name = 'polls'
# detail, results の <int:question_id> を、 <int:pk> に修正
# views.index を views.IndexView.as_view() に修正
# views.detail を views.DetailVIew.as_view() に修正
# views.result も同様に修正
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
from django.http import HttpResponseRedirect # HttpResponse は不要となった
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic # django.views.generic をインポート
from .models import Choice, Question
# リストを表示するページでは、ListViewを継承してクラス定義を行うと良い
class IndexView(generic.ListView):
# template_name を指定しない場合、"polls/question_list.html"が自動的に指定される
template_name = 'polls/index.html'
context_object_name = 'latest_question_list' # コンテキスト
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]
# 詳細ページでは、generic.DetailViewを継承してクラス定義を行うと良い
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
# ...
ここでは、ListView と DetailView を使用しています。
これらのビューはそれぞれ、「オブジェクトのリストを表示する」および「あるタイプのオブジェクトの詳細ページを表示する」という二つの概念を抽象化しています。