갈루아의 반서재

제너릭 뷰 시스템을 사용할 수 있도록 poll 앱을 수정해보자. 그러면 상당량의 코드를 지울 수 있다. 


1. URLconf 변환

2. 오래되고 불필요한 뷰 삭제

3. 장고의 제네릭 뷰에 입각한 새로운 뷰 도입


Amend URLconf


/root/mysite/polls/urls.py

from django.conf.urls import url


from . import views


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'),

    

]

2, 3번째 정규표현식의 패턴이 question_id>에서 <pk>로 바뀌었다.


Amend views





/root/mysite/polls/views.py

from django.shortcuts import get_object_or_404, render

from django.http import HttpResponseRedirect, HttpResponse, Http404

from django.core.urlresolvers import reverse

from django.views import generic

from django.template import RequestContext, loader

from .models import Choice, Question

from gc import get_objects


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):

    p = get_object_or_404(Question, pk=question_id)

    try:

        selected_choice = p.choice_set.get(pk=request.POST['choice'])

    except (KeyError, Choice.DoesNotExist):

        # Redisplay the question voting form.

        return render(request, 'polls/detail.html', {

            'question': p,

            'error_message': "You didn't select a choice.",

        })

    else:

        selected_choice.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=(p.id,)))    


우리는 위의 예에서 ListView 와 DetailView 라는 2개의 제네릭 뷰를 사용하고 있다. 각각의 뷰는 “오브젝트 리스트 보여주기” 그리고 “특정 타입의 오브젝트의 상세 페이지 보여주기”라는 컨셉을 나타낸다. 


각각의 제네릭 뷰는 어떤 모델에 적용되어야 하는지 알아야 하는데, 이는 모델 속성을 통해 드러난다. 


DetailView 라는 제네릭 뷰는 "pk"라고 부르는 URL로부터 캡쳐한 프라이머리 키를 요구하고, 따라서 question_id 를 pk 로 변경할 수 있다.


기본적으로, DetailView 라는 제네릭 뷰는 <app name>/<model name>_detail.html 의 형태의 템플릿을 사용한다. 위의 예에서 "polls/question_detail.html"을 쓰는 것처럼 말이다. template_name 속성은 장고로 하여금 자동생성되는 기본 템플릿 이름말고 특정한 템플릿 이름을 쓸 수 있게 해준다. 



'프로그래밍 Programming' 카테고리의 다른 글

[django] More comprehensive tests  (0) 2015.07.28
[django] Writing our first test  (0) 2015.07.25
[django] Write a simple form  (0) 2015.07.18
[django] Namespacing URL names  (0) 2015.07.18
[django] Use the template system  (0) 2015.07.18