[前回] 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アプリを汎用ビューに刷新しました。
次回も続きます。お楽しみに。