당신은 멋쟁이, 우리는 장고쟁이~

0%

Writing your first Django app, part3 - 3편

실제로 무언가를 하는 view 작성하기


각각의 뷰는 두가지중 하나를 실행 하도록 되어 있습니다.


  1. 요청된 페이지의 컨텐츠를 포함하고 있는 HttpResponse 객체를 반환
  2. Http404 같은 예외를 발생

나머지 동작은, 개발자 마음대로 입니다~



view 는 데이터베이스에서 기록을 읽어 올수 있고,

Django 가 제공하는 혹은 파이썬 템플릿 시스템들을 사용 할수 있고.

PDF, XML, ZIP 같은 파일등을 생성할수도 있습니다


어떤 파이썬 라이브러리든지 사용해서 View 가 작업을 수행할수 있습니다.


편의성 측면에서, Django 가 원하는건 단지 두가지 뿐입니다. HttpResponse 혹은 예외 처리 뿐입니다.


Part 2 에서 진행 했었던, database API 를 사용해서, index() view 를 한번 실행 해 봅시다


polls/views.py 의 index 뷰를

시스템에 존재하는 가장 최근의 질문들 5개를 출력하게 합니다

질문들은 날짜별로 , 으로 구분되게 합니다


index() 뷰를 아래와 같이 수정해 줍니다


1
2
3
4
5
6
7
8
9
10
11
12
13
from django.http import HttpResponse 

from .models import Question


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

# 다른 view 들 (detail, results, vote) 는 수정하지 않습니다.
# [q.question_text for q in latest_question_list] 는 list comprehension
# ', '.join 으로 list comprehension 안에 값들을 콤마로 구분 합니다


파트 2에서, Question.objects.all() API 를 둘러보았었는데,


이번에는, Question.objects.order_by('-pub_date')[:5] 가 나왔습니다.


Question 에 있는 객체 중,

가장 최근의 pub_date 순으로 5개를 조회 하는 쿼리를 실행

Question.objects.order_by(‘-pub_date’)[:5]


Question에 있는 모든 객체 조회 쿼리,

Question.objects.all()



근데 여기에, 문제가 좀 있습니다.


뷰에 있는 HttpResponse 값은 하드코드가 된 페이지 디자인 입니다. 페이지의 모양을 바꾸고 싶으면,


이 파이썬 코드를 매번 바꿔줘야 합니다. 코드가 짧을때는 상관 없겠지만, 페이지가 길면, 더 큰 문제가 될수 있고.


무엇보다, 디자인이 예쁘지 않습니다.



따라서,

Django의 템플릿 시스템을 사용하여 디자인과 파이썬 코드를 분리합니다

view 가 사용할수 있는 템플릿을 생성해서 사용합니다.


Template 생성하기



index.html 파일 생성하기


polls 폴더내에, templates 라는 폴더를 생성합니다.


Django 는 기본적으로 App 폴더안에 있는 Templates 폴더를 찾아서, Template 파일을 확인하고, 그것을 본 뒤에, 브라우저에 출력을 해줍니다.


polls 앱에서 사용하는 templates 는 polls/templates/ 폴더 안에 있는 파일들이겠죠?


생성한 templates 폴더안에, index.html 파일을 생성합니다

polls/templates/polls/index.html




템플릿 이름 공간

장고는 이름과 일치하는 첫번째 템플릿을 선택할 것이고,

다른 응용 프로그램에 같은 이름의 템플릿이 있다면, 장고는 그것을 구별할수 없습니다.


우리는 장고가 올바른 템플릿을 찾게 만들어줘야 하고,

이것을 확실히 하기 위한 가장 좋은 방법은, 그들의 이름을 붙여주는것입니다.


즉, 어플리케이션 자체를 위해 명명된 템플릿 폴더안에,

다시한번, 어플리케이션 이름을 가진 폴더를 생성하여

(polls/templates/polls/index.html)

다른 이름공간에 존재하는 템플릿을 구분하게 만들어 주는 것입니다.



index.html 파일 내용 추가


polls/templates/polls/index.html 파일에 아래 내용을 추가해줍니다.


1
2
3
4
5
6
7
8
9
{% 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 %}



1
2
3
4
5
# {% %} 안에 들어 있는 내용들은 템플릿 언어 입니다. 로직 혹은 구문들을 사용할수 있습니다. 

# {{}} 안에 들어 있는 내용도 템플릿 언어 인데, 변수들을 표시할수 있습니다.

# html 에서 이 템플릿 언어를 사용하여, 해당 데이터들을 다룰수 있습니다.

View 에서 index.html 파일을 템플릿으로 사용



polls/views.py 파일을 아래와 같이 수정해 줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.http import HttpResponse
from django.template import loader # 템플릿 파일을 불러오기 위한 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')

# template 에 전달할 객체 latest_question_list 를 사전 형태로 저장

context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))
# render 를 사용하여, template에서 사용할 객체 latest_question_list 를 template 에 출력해줌



해당 코드는 polls/index.html 템플릿 파일을 읽어오고, 거기에 context 를 전달합니다.


context 는 사전형태로, 메핑된 파이썬 객체에 할당된 템플릿 변수 이름들입니다.

1
2
# 이 템플릿 변수가 html 에 전달이 되면, 
# 위에 나온 `{% %}` 나 `{{ }}` 같은 템플릿 언어를 사용하여, 데이터들을 다룰수 있습니다.

브라우저에 접속해서,

http://127.0.0.1:8000/polls/ 에 접속합니다.

part2 에서 입력하였던, What’s up? 질문이 화면에 표시됩니다.




마치며..


처음에 굉장히 헷갈리는 개념입니다.

view 를 어떻게 작성해야 할지,

어떻게 URL에 연결해줘야 할지,

어떤 Template 을 끄집어내서 사용할지,,,

계속 아래 그림을 생각하면서, view 가 어떤 역할을 하는지 이해하려 하고 넘어갑니다.