-
Part 3 뷰와 템플릿Django 2022. 7. 1. 18:41
view는
일반적으로 특정한 기능을 제공하고 특정한 템플릿을 가진
Django 애플리케이션에 있는 웹 페이지의 “type”입니다.
우리가 만드는 poll 어플리케이션에서 다음과 같은 네개의 view 를 만들어 보겠습니다.
- 질문 “색인” 페이지 – 최근의 질문들을 표시합니다.
- 질문 “세부” 페이지 – 질문 내용과, 투표할 수 있는 서식을 표시합니다.
- 질문 “결과” 페이지 – 특정 질문에 대한 결과를 표시합니다
- 투표 기능 – 특정 질문에 대해 특정 선택을 할 수 있는 투표 기능을 제공합니다.
뷰 추가하기
polls/view.py에 뷰를 추가해 봅시다.
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)뷰에서는 request라는 인자를 받고 HttpResponse라는 함수를 return하게 됩니다.
뷰를 호출하기 위해서 url코드를 작성하도록 하겠습니다.
polls/urls.py에 다음과 같이 입력해주세요.
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]뷰가 실제로 뭔가를 하도록 만들기
index( ) 뷰 하나를 호출했을 때,
Hello world 대신 Question을 직접 가져와서 출력하도록 하겠습니다.
polls/view.py에 index부분을 다음과 같이 수정해 주세요.
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)
# Leave the rest of the views (detail, results, vote) unchangedindex() 뷰 하나를 호출했을 때,
시스템에 저장된 최소한 5 개의 투표 질문이 콤마로 분리되어, 발행일에 따라 출력됩니다.
만약 페이지가 보여지는 방식을 바꾸고 싶다면, 이 Python 코드를 편집해야만 할겁니다.
그럼, 뷰에서 사용할 수 있는 템플릿을 작성하여,
Python 코드로부터 디자인을 분리하도록 Django의 템플릿 시스템을 사용해 봅시다.템플릿을 작성해보고 뷰 소스도 수정하여 템플릿과 연결하도록 하겟습니다.
폴스 안에 템플릿 디렉토리를 만들어 주면 되는데
템플릿 디렉토리내의 앱이름으로 디렉토리를 또 하나 만들어 html파일을 관리하면 됩니다
(이런 구분없이 템플릿 안에 그냥 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 뷰를 업데이트 해보도록 하겠습니다.
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 템플릿을 불러온 후, context를 전달합니다.
render함수를 사용하면 코드내용을 줄일 수 있습니다.
loader , HttpResponse 함수를 import하지 않고
render를 사용하여 한줄로 작성하면 됩니다.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)404 에러 일으키기
question_id를 전달받고 Question을 조회를 했을 때 데이터가 없는 경우
"Question does not exist"라는 문구가 보여지도록
polls/views.py에 detail 부분을 다음과 같이 수정해 보겠습니다.from django.http import Http404
from django.shortcuts import render
from .models import Question
# ...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})detail 템플릿도 만들어 작성해 줍니다.
없는 데이터를 조회하게 우리가 처리한 예외 메시지를 다음과 같이 확인할 수 있습니다.
(ex 127.0.0.1:8000/polls/2/)
Http404 예외처리는 데이터를 조회할 때 자주 쓰이는 용법입니다.
장고에서는 이 기능에 대한 단축 기능(shortcuts)을 제공합니다.
try, except 없이 shortcuts를 이용하여 detail( )뷰를 다음과 같이 수정하여도
동일한 화면을 확인할 수 있습니다.
from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})템플릿 시스템 사용하기
detail( )뷰로 되돌아가
context 변수 question이 주어졌을때, polls/detail.html이라는 템플릿이 어떻게 보이는지 봅시다.
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>question.question_text인 What's new?가 보이고
question에 대한 choice들(Red, Blue, Green)이 보입니다.
더보기기존에 만들어놓은 choice 목록이 없어서 추가하여 확인했습니다.
admin에서 Choice 항목을 생성 후
관리자 페이지에서 choice 목록을 추가했습니다!
템플릿에서 하드코딩된 URL 제거하기 및 URL의 이름공간 정하기
polls/index.html 템플릿에 링크를 적으면,
이 링크는 다음과 같이 부분적으로 하드코딩됩니다.
URL 변경시 템플릿에 있는 코드들도 변경해 주어야 합니다.
장고에서는 URL마다 이름을 설정할 수 있습니다.
URL 코드에 이름을 설정하고 템플릿에 이름을 직접 써 주게 되면
하드코딩된 URL이 변경되더라도 고유이름을 갖고 있기 때문에
템플릿 URL 대해서는 소스코드 변경을 할 필요가 없습니다.다른 앱에서도 detail에 대한 URL 이름을 사용할 수 있기 때문에
해당 앱에서 사용하는 URL에 대해서는 앱이름을 설정해주면 됩니다.
이름을 설정해주고 템플릿에 추가하면 됩니다.출처 : django 웹 프로그래밍 강좌 (#3 view)(django view 사용, html 불러오기 및 연결)
'Django' 카테고리의 다른 글
Part 5 테스팅 (0) 2022.07.02 Part 4 폼과 기본 뷰 (0) 2022.07.02 Part 2-2 관리자 페이지 (0) 2022.06.29 part 2-1 모델 (0) 2022.06.29 part 1. 요청과 응답 (0) 2022.06.28