
目次
はじめに
Django を学習するには、何はともあれ公式チュートリアル「はじめての Django アプリ作成」からスタートしてみるのが良いでしょう。しかし、いざチュートリアル通りに進めようとしても躓く場合も多いと思います。そこで、「チュートリアルの進め方」シリーズとして、チュートリアルに沿った作業を行いながら補足事項をまとめることにしました。チュートリアルで躓いた際のヒントとしてお使いください。
利用環境は Ubuntu、 Linux Mint を中心として説明しますが、 Windows についても補足します。
前回は、Django チュートリアルの進め方 その 4 (1) と題してはじめての Django アプリ作成、その 4の前半についてまとめました。
今回は、はじめての Django アプリ作成、その 4 の後半についてまとめました。
汎用ビューを使う: コードが少ないのはいいことだ
ここまでのチュートリアルで記述してきたビューの書き方は、基本形ではありますが、実践ではクラスベースのビュー (汎用ビュー) を使った記述を中心とし、それで対応できない場合にこれまでのような関数ベースのビューで記述することになります。ここからは、ビューをクラスベースに書き換えて行きます。
URLconf の修正
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, result をクラスベースの汎用ビューに置き換えます。それぞれ IndexView, DetailView, ResultsView というクラスを定義します。これらのクラスは as_view() を使って path() メソッドにビューを提供できます。
また、プライマリキーは 'pk' で指定します。
views の修正
polls.views を書き換えます。
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 django.db.models import F 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): question = get_object_or_404(Question, pk=question_id) try: selected_choice = question.choice_set.get(pk=request.POST['choice']) except (KeyError, Choice.DoesNotExist): # Redisplay the question voting form. return render(request, 'polls/detail.html', { 'question': question, 'error_message': "You didn't select a choice.", }) else: selected_choice.votes = F('votes') + 1 selected_choice.save() # Always return an HttpResponseRedirect after successfully dealing # with POST data. This prevents data from being posted twice if a # user hits the Back button. return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
各ビューに対応するクラスを、汎用クラスから派生させます。
IndexView は generic.ListView から派生されています。
ListView のデフォルトのテンプレート名は モデル名+_list + .html (_list は template_name_suffix 属性で定義された値) ですが、ここでは作成済のテンプレート名を template_name 属性で明示的に指定しています。また、コンテキスト変数名は、デフォルトでは モデル名+_list ですが、同様に context_object_name 属性で明示的に先に使用していた変数名を指定しています。
class django.views.generic.list.ListView
オブジェクトのリストを表示するページを表現する
[属性]- template_name: テンプレート名
- context_object_name: コンテキストで使用する変数の名前を指定
- template_name_suffix: 自動生成された候補テンプレート名に追加する接尾辞 (デフォルトは _list)
- get_queryset(): このビューの項目リストを取得する
- get_context_object_name(): コンテキスト変数名を返す (デフォルトはモデル名+_list)
DetailView と ResultView は generic.DetailView から派生されています。
model 属性でモデルを指定し、template_name 属性でテンプレート名を指定しています。template_name_suffix 属性のデフォルト値が _detail なので、デフォルトのテンプレート名は モデル名 + _detail + .html になりますが、明示的に指定しています。
また、generic.DetailView でテンプレートに渡される変数名 (コンテキスト変数名) は、モデル名を小文字にしたものが自動的に使用されます。(get_context_object_name() で定義されている。)
class django.views.generic.detail.DetailView
オブジェクトの詳細を表示するページを表現する
このビューが動作している間、self.object はビューが操作しているオブジェクトを含む
→ テンプレート上では、{{ object.フィールド名 }} として対象となるフィールド値にアクセスできる
[属性]- model: このビューが表示するモデル
- template_name: テンプレート名
- template_name_suffix: 自動生成されたテンプレート名候補に追加する接尾辞 (デフォルトは _detail)
- get_context_object_name(): コンテキスト変数名を返す (デフォルトはモデル名を小文字にしたもの)
参考
-
- Django チュートリアルの進め方 その 1
- Django チュートリアルの進め方 その 2 (1)
- Django チュートリアルの進め方 その 2 (2)
- Django チュートリアルの進め方 その 2 (3)
- Django チュートリアルの進め方 その 3 (1)
- Django チュートリアルの進め方 その 3 (2)
- Django チュートリアルの進め方 その 4 (1)
- Django チュートリアルの進め方 その 4 (2)
- Django チュートリアルの進め方 その 5 (1)
- Django チュートリアルの進め方 その 5 (2)
- Django チュートリアルの進め方 その 6
- Django チュートリアルの進め方 その 7