kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

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.indexviews.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の拡張だし