[前回] Django+Reactで学ぶプログラミング基礎(8): Djangoチュートリアル(投票アプリその4-1)
はじめに
Django公式チュートリアル、その4-2です。
前回は、アプリにフォームを追加しました。
今回は、汎用ビューについてです。
Djangoアプリ作成(その4-2): 投票(poll)アプリ
今回の内容
- 汎用ビューを使用
汎用ビューを使う
- 汎用ビューとは
- よくあるパターンを抽象化し、Pythonコードすら書かずアプリを書き上げられる
- コードが少ないのはいいことだけど、どうやって実現する?
 
 
- よくあるパターンを抽象化し、Pythonコードすら書かずアプリを書き上げられる
- 投票アプリを汎用ビューシステムに変換し、 コードをばっさり捨てる
- 変換は数ステップ
- 
URLconfを変換
- 古い不要なビューを削除
- 新しいビューにDjango汎用ビューを設定
 
- 
 
- 変換は数ステップ
- コードを入れ換える
- Djangoアプリを書く場合、最初から自分の問題解決に適している汎用ビューを使用
- チュートリアルでは、説明のため途中から汎用ビューに変更
 
 
- Djangoアプリを書く場合、最初から自分の問題解決に適している汎用ビューを使用
URLconfを修正
- 汎用ビュー向けにquestion_idをpkに変更- 汎用ビューの場合、URLからpkという名前でプライマリキーをキャプチャし、汎用ビューに渡しているため
- 2つ目と3つ目のパス文字列に該当するパターン名を<question_id>から<pk>に変更
 
- 汎用ビューの場合、URLから
polls/urls.py
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'),
]
ビューの修正
- 古いindex、detail、resultsのビューを削除
- 代わりに、Djangoの汎用ビューを使用
- 
ListView汎用ビュー- 
オブジェクトのリストを表示するという概念を抽象化
 
- 
- 
DetailView汎用ビュー- 
あるタイプのオブジェクトの詳細ページを表示するという概念を抽象化
 
- 
 
- 
- 汎用ビューとモデルのマッピング
- 
model属性を使用
 
- 
- 汎用ビューのテンプレート
- デフォルトで、 汎用ビューが使用するテンプレート
- 
DetailView汎用ビューの場合- <app name>/<model name>_detail.html
- 例えば、polls/question_detail.html
 
- 
ListView汎用ビューの場合、- <app name>/<model name>_list.html
 
 
- 
- 結果ビューResultViewと詳細ビューDetailViewは、同じDetailView汎用ビューを使用- 
template_name属性を指定し、異なる見た目にレンダリング可能- 自動生成のデフォルトテンプレート名ではなく、指定テンプレート名を使うよう Djangoに伝える
 
 
- 
- 索引ビューIndexViewは、ListView汎用ビューを使用- 
template_name属性を指定し、polls/index.htmlテンプレートを使用するように指示
 
- 
 
- デフォルトで、 汎用ビューが使用するテンプレート
- テンプレートに渡すコンテキスト変数
- 
DetailViewに、questionというコンテキスト変数が自動的に渡される- 理由は、モデルQuestionとマッピングされているため、Djangoがコンテキスト変数にふさわしい名前を決めてくれる
 
- 理由は、モデル
- 
ListViewに、question_listというコンテキスト変数が自動的に渡される- 上書きするには、context_object_name属性を使用
- 代替アプローチとして、テンプレート名をデフォルトのコンテキスト変数名と一致させることもできる
- ただし、使用したいコンテキスト変数名をDjangoに伝えたほうが簡単
 
 
- 上書きするには、
 
- 
polls/views.py
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
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 the last five published questions."""
        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'
def vote(request, question_id):
    ... # same as above, no changes needed.
サーバーを実行し、汎用ビューベースに変更した投票アプリを検証
- VS Codeターミナルで、仮想環境をアクティベート
C:\kanban\pollsite>..\venv\.venv\Scripts\activate
- 開発サーバーを起動
(venv) C:\kanban\pollsite>python manage.py runserver
質問をクリックします。
投票してみます。
おわりに
Djangoアプリを汎用ビューに刷新しました。
次回も続きます。お楽しみに。


