Korean translation of http://www.djangoproject.com/documentation/tutorial4

<--

[../Tutorial3]

[../Tutorial1]

-->

당신의 첫번째 장고 프로그램 만들기, part 4

이 문서는 Django 0.9.1을 다룬다. 구버전 : 0.90 docs

By Adrian Holovaty <holovaty@gmail.com>, Translated by [parkpro77]

간단한 형태 작성하기

마지막 튜토리얼로부터 투표 세부 템플릿 (poll detail template)을 업데이트하고 나서, 템플릿에 HTML <form> 요소를 포함하자:

   1 <h1>{{ poll.question }}</h1>
   2 
   3 {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
   4 
   5 <form action="/polls/{{ poll.id }}/vote/" method="post">
   6 {% for choice in poll.get_choice_list %}
   7     <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
   8     <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
   9 {% endfor %}
  10 <input type="submit" value="Vote" />
  11 </form>

빠른 요약:

  • 위의 주형은 각 투표 선택을 위한 라디오 버튼 (radio butten)을 보여준다. 각 라디오 버튼의 값은 투표 선택의 ID와 관련되어져 있다. 각 라디오 버튼의 이름은 "choice" 이다. 어떤 사람이 라디오 버튼 중 하나를 선택하고 그 형태를 전송할 때, 그것은 POST 데이타인 choice=3 을 보낼 것이다. 이것은 HTML Forms 101 이다.
  • 우리는 /polls/poll.id/vote/ 로 형태의 액션 (form's action)을 구성했고, method="post" 로 구성했다. (method="get" 과는 반대로서) method="post" 를 사용하는 것은 전송하는 행위가 서버 측의 데이타를 개조할 것이기 때문에 매우 중요하다. 서버 측의 데이타를 바꿔주는 형태를 만들때마다 method="post" 를 사용하라. 이 팁은 장고에게는 중요하지 않다; 그것은 단지 좋은 웹을 개발하는 행위일 뿐이다.

이제, 전송된 데이타를 처리하고, 어떤것을 하는 보기를 만들자. 튜토리얼3에서 이 라인이 포함되어진 URLconf를 만들었다는 것을 기억하라:

r'^polls/(?P<poll_id>\d+)/vote/$', 'myproject.polls.views.vote'),

그래서, myproject/polls/views.py 에서 vote() 기능을 만들자:

   1 from django.core.extensions import get_object_or_404, render_to_response
   2 from django.models.polls import choices, polls
   3 from django.utils.httpwrappers import HttpResponseRedirect
   4 
   5 def vote(request, poll_id):
   6     p = get_object_or_404(polls, pk=poll_id)
   7     try:
   8         selected_choice = p.get_choice(pk=request.POST['choice'])
   9     except (KeyError, choices.ChoiceDoesNotExist):
  10         # Redisplay the poll voting form.
  11         return render_to_response('polls/detail', {
  12             'poll': p,
  13             'error_message': "You didn't select a choice.",
  14         })
  15     else:
  16         selected_choice.votes += 1
  17         selected_choice.save()
  18         # Always return an HttpResponseRedirect after successfully dealing
  19         # with POST data. This prevents data from being posted twice if a
  20         # user hits the Back button.
  21         return HttpResponseRedirect('/polls/%s/results/' % p.id)

이 코드는 우리가 이 튜토리얼에서 아직 적용해보지 못했던 몇 가지를 포함한다:

  • request.POST 는 키 이름에 의해 전송된 데이타가 접근하는 형식의 사전과 비슷한 객체이다. 이 경우에, request.POST['choice'] 는 문자로서 선택된 choice의 ID를 되돌린다. request.POST 값은 항상 문자열들이다. 같은 방법으로 GET 데이타에 접근하기 위해서 장고는 request.GET 을 제공한다 -- 그러나, 데이타가 오직 POST 호출을 경유해서 바뀐다는 것을 확실하게 하기 위해서 우리는 코드에서 명백하게 request.POST 를 사용하고 있다.
  • request.POST['choice'] 는 choice가 POST 데이타 안에 제공되어지지 않았다면, KetError를 일으킬 것이다. 위에 코드는 KeyError를 검사하고, 만약 choice가 주어지지 않았다면 에러 메세지와 함께 투표 형태 (poll form)를 다시 보여준다.

  • choice의 수가 증가한 후에, 표준 HttpResponse 보다는 HttpResponseRedirect를 되돌린다. HttpResponseRedirect는 하나의 인수를 얻는다: 사용자가 방향을 바꿀것 같은 URL. 할 수 있다면, http:// 와 도메인 이름은 쓰지 않아도 될 것이다. 그것은 도메인과 접촉되어 당신의 투표를 돕는다.

위에서 지적한 파이썬 주석에 따라, POST 데이타를 완전히 처리한 후에 항상 HttpResponseRedirect를 되돌린다. 이 팁은 장고에게는 특별하지 않다; 그것은 단지 좋은 웹을 개발하는 행위일 뿐이다.

튜토리얼3에서 언급한 것에 따라, request는 HTTPRequest 객체이다. HTTPRequest에 대해 더 알고 싶다면, request and response documentation을 보아라.

어떤 사람이 poll에서 투표한 후에, vote() 보기는 poll을 위해 결과 페이지를 고쳐 쓴다. 그 보기를 작성하자:

   1 def results(request, poll_id):
   2     p = get_object_or_404(polls, pk=poll_id)
   3     return render_to_response('polls/results', {'poll': p})

이것은 튜토리얼3의 detail() 보기와 거의 똑같다. 오직 다른 점은 주형 이름이다. 우리는 후에 이 반복을 고정시킬 것이다.

이제, result.html 주형을 만들자:

   1 <h1>{{ poll.question }}</h1>
   2 <ul>
   3 {% for choice in poll.get_choice_list %}
   4     <li>{{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
   5 {% endfor %}
   6 </ul>

이제, 웹 브라우저에서 /polls/1/으로 가서, poll에서 투표하라. 당신은 각 시간에 당신이 투표해서 업데이트된 결과 페이지를 볼 것이다. 만약 choice의 선택없이 그 형태를 전송한다면, 당신은 에러 메세지를 보게 될 것이다.

일반적인 보기들 사용하기: 적은 수의 코드가 더 좋다

detail() ([../Tutorial3])과 result() 보기들은 너무나 간단하다 -- 그리고, 위에서 언급했던 것처럼 반복이 있다. 투표들의 목록을 보여주는 index() 보기 ([../Tutorial3])는 유사하다.

이런 보기들은 기초적인 웹 개발 -- URL에서 통과된 변수에 따라 데이타베이스로부터 데이타를 얻고, 주형을 적재하고, 넘겨진 주형을 되돌린다 -- 에 평범한 경우이다. 이것은 매우 일상적이기 때문에, 장고는 "일반적인 보기들 (generic views)" 시스템을 호출할 단축키를 제공한다.

일반적인 보기들은 투표를 작성하기 위해 파이썬 코드를 작성하는 것이 필요하지 않다는 점에 평범한 형태로 전환한다.

자신의 코드 묶음을 지울 수 있게 하기 위해서 일반적인 보기 시스템을 사용하여 투표 프로그램을 변환하자. 변환하기 위해 몇 단계를 거쳐야만 한다.

{{| 왜 코드를 섞나?

일반적으로, 장고 프로그램을 작성할 때, 일반적인 보기들이 당신의 문제에 적합한지 평가할 것이고, 당신의 코드가 절반까지 리팩토링 되어 있는 것보다는 처음부터 그것을 사용할 것이다. 그러나, 이 튜토리얼은 핵심적인 개념에 발맞추기 위해 지금까지도 보기들을 작성하는데 의도적으로 "힘든 길"을 걸어왔다.

당신은 계산기를 사용하기 전에 기본적인 수학을 알 것이다. |}}

첫번째로, polls.py URLconf를 열어라. 그것은 이 전까지의 튜토리얼에 따라 이와 같이 보인다:

   1 from django.conf.urls.defaults import *
   2 
   3 urlpatterns = patterns('myproject.polls.views',
   4     (r'^$', 'index'),
   5     (r'^(?P<poll_id>\d+)/$', 'detail'),
   6     (r'^(?P<poll_id>\d+)/results/$', 'results'),
   7     (r'^(?P<poll_id>\d+)/vote/$', 'vote'),
   8 )

그것을 이와 같이 바꿔라:

   1 from django.conf.urls.defaults import *
   2 
   3 info_dict = {
   4     'app_label': 'polls',
   5     'module_name': 'polls',
   6 }
   7 
   8 urlpatterns = patterns('',
   9     (r'^$', 'django.views.generic.list_detail.object_list', info_dict),
  10     (r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
  11     (r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results')),
  12     (r'^(?P<poll_id>\d+)/vote/$', 'myproject.polls.views.vote'),
  13 )

여기에서 두 개의 일반적인 보기들을 사용하고 있다: object_list와 object_detail. 각각은, "객체들의 목록을 보여준다."와 "객체의 특별한 형식을 위한 세부 페이지를 보여준다" 라는 개념들을 가지고 있다.

  • 각 일반적인 보기는 실제적으로 쓰고 있는 app_label과 module_name 을 아는 것이 필요하다. 그래서, 우리는 URL 튜플들에 세번째 변수들을 경유하여 각각의 일반적인 보기들을 통과하는 사전인 info_dict를 정의했었다.
  • URL로부터 입력된 ID 값은 "object_id" 로 불리워진다고 object_detail은 예상한다. 그래서, 일반적인 보기들을 위해 poll_id를 object_id로 바꿨었다.

초기설정에 의해, object_detail 은 <app_label>/<module_name>_detail 이라 불리우는 주형을 사용한다. 우리의 경우, "polls/polls_detail" 주형을 사용할 것이다. 그래서, polls/detail.html 주형의 이름을 polls/polls_detail.html 로 이름을 바꾸고, vote() 안에 render_to_response() 라인을 변경하라.

유사하게, object_list 는 <app_label>/<module_name>_list 라 불리우는 주형을 사용한다. 그래서, polls/index.html 을 polls/polls_list.html 로 이름을 변경하라.

왜냐하면, 우리는 polls 프로그램을 위해 object_detail 을 사용하는 URLconf에서 한 항목 (entry)보다 더 많이 가지고 있기 때문에, 결과들의 보기를 위해 주형의 이름을 명확히 말한다: template_name='polls/results'. 반면, 보기 둘 다 같은 주형을 사용할 것이다. 적소에 변경되 사전을 되돌리기 위해서 dict() 를 사용하는 것에 주목하라.

일반적인 보기들은 object와 object_list를 그것들의 주형들로 넘긴다, 그래서 latest_poll_list 는 object_list 가 되고, poll 은 object 가 되기 위해서 당신의 주형들을 변경하라.

vote() 보기에서, polls/detail 을 polls/polls_detail 로 주형 호출을 변경하라. 그리고, poll 대신에 내용에서 object를 넘겨라.

마지막으로, polls/views.py 로부터 index(), detail(), results() 보기들을 삭제할 수 있다. 그것들은 더 이상 필요하지 않다.

일반적인 보기들을 더 자세히 알고 싶으면, generic views documentation 을 참고하라.

개봉 박두

우선은 여기까지가 튜토리얼의 끝이다. 하지만, 다음 분량을 위해 다시 만날 것이다:

  • 진보한 기술 과정
  • RSS 구조 (framework) 사용하기
  • 캐시 구조 사용하기
  • 주석 구조 사용하기
  • 진보한 관리자 특징 : 허용 (permissions)
  • 진보한 관리자 특징 : 일반적인 자바 스크립트

Django/Tutorial4 (last edited 2011-08-03 11:00:46 by localhost)

web biohackers.net