갈루아의 반서재

각각의 뷰는 다음의 2가지 기능을 수행한다. 하나는 요청한 페이지의 컨텐츠를 담고 있는 HttpResponse 객체트를 반환하는 것이고, 다른 하나는 Http404 같은 예외를 선언하는 것이다. 

뷰는 데이터베이스에서 레코드를 읽어오거나 또는 읽어오지 못한다. 장고나 또는 써드 파티 파이썬 템플릿을 사용하거나 또는 사용하지 못한다. 파이썬 라이브러리를 활용하여 PDF 파일을 생성하거나, XML 을 도출하거나, ZIP 파일을 생성하기도 한다. 장고는 HttpResponse 또는 예외를 원하는 것이다. 그러면 장고의 데이터베이스 API 를 이용하여 최근 5개의 질문을 뽑아내는 예제를 만들어보자.


/root/mysite/polls/views.py

from django.shortcuts import render

from django.http import HttpResponse
from django.template import RequestContext, loader
from .models import Question

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    output = ', '.join([p.question_text for p in latest_question_list])
    return HttpResponse(output)

def detail(request, question_id):
    return HttpResponse("You're looking at the question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the result of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on qeustion %s." % question_id)

# Create your views here.


그런데 문제가 하나 있다. 위의 예제는 하드 코딩이라는 점이다. 템플릿을 만들어서 디자인 부분을 분리시켜보자.

/root/mysite/polls/templates 디렉토리생성

→ /root/mysite/polls/templates/polls 디렉토리생성 

→ 해당 디렉토리내에 index.html 생성


Template namespacing

또 다른 polls 서브 디렉토리를 만들지 않고도 polls/templates 에 직접 템플릿을 담을 수 있게 되었다. 하지만 이건 그리 좋은 아이디어가 아니다. 장고는 이름이 일치하는 첫 번째 템플릿을 선택할 것이기 때문이다. 그리고 만약 서로 다른 어플리케이션에 같은 이름을 가진 템플릿이 있다면, 장고는 그 둘을 서로 구별하지 못하기 때문이다. 장고가 정확히 하나의 템플릿을 가리킬 수 있도록 해야 한다. 네임스페이싱을 이용하여 해당 템플릿을 별도의 디렉토리에 넣어둔다. 

polls/templates/polls/index.html

{% if latest_question_list %}

    <ul>

    {% for question in latest_question_list %}

        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

    {% endfor %}

    </ul>

{% else %}

    <p>No polls are available.</p>

{% endif %}


그리고 아래 views.py 파일을 아래와 같이 업데이트하자.

/root/mysite/polls/views.py

from django.shortcuts import render

from django.http import HttpResponse

from django.template import RequestContext, loader

from .models import Question


def index(request):

    latest_question_list = Question.objects.order_by('-pub_date')[:5]

    template = loader.get_template('polls/index.html')

    context = RequestContext(request, {

         'latest_question_list': latest_question_list, 

    })

    return HttpResponse(template.render(context))


def detail(request, question_id):

    return HttpResponse("You're looking at the question %s." % question_id)


def results(request, question_id):

    response = "You're looking at the result of question %s."

    return HttpResponse(response % question_id)


def vote(request, question_id):

    return HttpResponse("You're voting on qeustion %s." % question_id)


# Create your views here.


위의 코드는 polls/index.html 을 호출하고 아래와 같이 불렛 리스팅 페이지를 보여준다.


해당 링크는 해당 설문의 상세 페이지를 보여준다.

A shortcut: render()¶

장고는 shortcut 을 제공한다. 
아래 예제를 보자.




polls/views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext, loader
from .models import Question

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

def detail(request, question_id):
    return HttpResponse("You're looking at the question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the result of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on qeustion %s." % question_id)



render() 함수는 리퀘스트를 첫번째 인수로, 템플릿을 두 번째 인수, 그리고 딕셔너리를 세번째 (선택적) 인수로 다룬다.