본문 바로가기

레퍼런스/장고 튜토리얼

장고(Django) 실제로 뭔가 작업을 하는 뷰를 만들기.

각 뷰는 두 가지 중 하나를 해야만 하는 책임이 있습니다: 요청된 페이지의 내용을 포함한 오브젝트를 반환하거나 HttpResponse를 반환하거나 Http404처럼 익셉션을 반환하는 것입니다. 나머지는 여러분께 달렸습니다.

 

여러분의 뷰는 데이터베이스에서 레코드를 읽어오거나 아닐 수 있습니다. 장고의 템플릿 시스템 - 혹은 서드파티 파이썬 템플릿 시스템 - 을 사용하거나 아닐 수도 있습니다. 파이썬 라이브러리를 사용해서 PDF 파일을 생성한다던지, XML을 출력한다던지, 즉석에서 ZIP 파일을 만드는 등의 작업을 할 수 있습니다.

 

설명하기 편하게 장고의 자체 데이터베이스 API를 사용하도록 하겠습니다. 게시일자를 포함하고 콤마로 구분되어 있는 적어도 5개의 질문을 보여주는 index() 뷰가 있습니다.

 

# polls/views.py

from django.http import HttpResponse

from .models import Question

def index(request):
	latest_question_list = Question.objects.order_by('-pub_date')[:5]
    output = ', '.join([q.question_text for q in latest_question_list])
    return HttpResponse(output)
    
# 나머지 뷰들은 (detail, results, vote) 변경하지 말고 두세요.

 

그런데 문제는 여기 있습니다: 뷰에서 페이지의 디자인은 하드코딩 돼 있습니다. 페이지의 외관을 바꾸려면 이 파이썬 코드를 편집해야합니다. 뷰가 사용할 수 있는 템플릿을 만들어서 장고의 템플릿 시스템을 분리시킬 겁니다.

 

먼저, polls 디렉코리에서 templates을 만듭니다. 장고는 그 곳에서 템플릿을 찾습니다.

 

여러분의 프로젝트의 TEMPLATES 설정에서 장고가 어떻게 템플릿을 가져오고 그리는지 알 수 있습니다. 기본 설정 파일이 APP_DIRS 옵션이 True로 설정된 DjangoTemplates 백엔드를 구성합니다. 관례적으로 DjangoTemplates는 각각의 INSTALLED_APPS에서 "templates" 하위 디렉토리를 찾습니다.

 

여러분이 방금 생성한 templates 디렉토리 안에서 polls라는 다른 디렉토리를 만듭니다. 그 안에서 index.html이라는 파일을 만들 겁니다. 여러분의 템플릿은 이제 polls/templates/polls/index.html을 만든겁니다. 위에서 app_directories 템플릿 로더가 어떻게 작동하는지 설명했듯이 장고 내에서 polls/index.html로 간단하게 참조가 가능합니다.

 

아래의 코드를 템플릿에 입력하세요 :

 

<!-- 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 %}

 

이제 polls/views.py에서 템플릿을 쓸 수 있게 바꿔서 index 뷰를 업데이트 해 보겠습니다:

 

# polls/views.py

from django.http import HttpResponse
from django.template import 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 = {'latest_question_list': latest_question_list,}
    return HttpResponse(template.render(context, request))

 

이 코드가 polls/index.html 템플릿을 가져와 컨텍스트에 넘겨줍니다. 컨텍스트는 파이썬 오브젝트에 템플릿 변수를 매핑합니다.

 

브라우저가 "/polls/"를 가리키게 하면서 페이지를 로드합니다. 

 

지름길: render()

 

템플릿의 공통적으로 자주 사용되는 구문은 컨텍스트를 채워서 HttpResponse 오브젝트를 렌더된 템플릿 결과와 함께 돌려받는 것입니다. 장고가 이에 대해서 지름길을 제공합니다. 다시 쓰여진 index() 뷰에요:

 

# polls/views.py

from django.shortcuts import render

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)

 

모든 뷰에 적용한다면, loaderHttpResponse를 import할 필요가 없어집니다(만약 detail, results, vote에서 stub 메소드를 가지고 있다면, HttpResponse를 유지해야합니다).

 

render() 함수는 request 객체를 첫번째 인자로 받고, 템플릿 이름을 두번째 인자로 받으며, 컨텍스트 딕셔너리 객체를 세번째 선택적(optional) 인자로 받습니다. 인자로 지정된 컨텍스트로 표현된 템플릿의 HttpResponse 객체가 반환됩니다.