Djangoチュートリアル(11) 汎用ビュー
さてなんだか同じようなコードが増えてきましたが
汎用ビュー(Generic View)ってやつでまとめられるそうな
これらのビューは基本的な Web開発の一般的なケースを表します。すなわち、 URL を介して渡されたパラメータに従ってデータベースからデータを取り出し、テンプレートをロードして、レンダリングしたテンプレートを返します。これはきわめてよくあることなので、 Django では、汎用ビュー(generic view)というショートカットを提供しています。
polls/urls.py をこうして
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
views.index
がviews.IndexView.as_view()
になってたり
(?P<question_id>[0-9]+)
が(?P<pk>[0-9]+)
になってたりする
vote
は変更なし
polls/views.py をこうすると
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'
同じことをするアプリになる
関数ではなくてクラスを定義するようになった
テンプレートを除けばどれも似たようなものってことか
テンプレートのファイル名を規約に沿って作ってればtemaplate_name
も省略できるとか
なんかブラックボックス感すごいけど
もとの形から考えたらそこまですごいわけじゃないのか
ListView
とかDetailView
とかのas_view()
はrender
を返してるのかな
いや違うか
as_view()
はdjango/views/generic/base.pyで定義されてる模様
@classonlymethod
def as_view(cls, **initkwargs):
...
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
...
return view
これがたとえば
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
と同じようなものかと言うとちょっとわからない
違っててもいいんだろうか
テンプレートさえ変えれば実はWebアプリなんてそんなもんよ、って感じなのかなあ
いや、継承して機能追加しなさいよ、ってことか
ListView
とかDetailView
だってView
の拡張だし