파트1, 파트2에서는 django의 기본적인 세팅 및 url, view 그리고 db관련한 모델(스키마) 만드는 법을 익혔습니다.
파트3에서는 위의 내용기반으로 web application을 만들어가기 시작합니다. web application은 사용자가 request 하면 요청의 따른 response를 해줍니다.
사용자에게 응답을(보여) 주기 위한 template에 대해서 다루게 됩니다. 순수 django를 사용한다면 앞단을 template로 분리를 해주지만 react와 같은 다른 프론트를 사용한다면 template를 사용하지는 않습니다.
views.py와 urls.py를 작성해보겠습니다.
polls/views.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)
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'),
]
cf) url 작성시 위와 같이 주석으로 예시 반드시 작성해주자.
브라우저에서 /polls/34/ 호출 시 detail view가 호출이 됩니다.
name를 작성해주는 이유는 name 앞의 인자들에 대한 alis 같은 존재입니다. template에서 다른 url을 호출 할 때 풀네임을 적어주는 것이 아닌 name만으로도 호출이 가능합니다.
question_id 이름 지정은 view에서 id를 인자로 받아 사용하기 때문에 네이밍도 중요합니다.
view가 리턴 하는 것은 2가지 중 하나입니다. HttpResponse 또는 Http404 둘 중 하나를 리턴합니다. view에서는 db에서만 데이터를 갖고 올 수 있는게 아닌 다양한 파이썬 라이브러리를 활용하여 pdf, xml 등등 데이터를 가공하여 리턴을 할 수도 있겠습니다.
위의 view는 출력 내용들이 하드코딩 되어 있습니다. 출력 내용이 변경 된다면 파이썬으로 되어 있는 view 코드를 수정해줘야 됩니다. 우리는 로직과 render되는 단을 분리해주기 위해서 template를 사용합니다.
template를 작성하고 로직을 담당하는 view를 수정해봅시다.
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$
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
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))
view에서는 template를 로드하여 HttpResponse를 통해서 응답을 준다.
위 대신 shortcut인 render을 사용해보자 (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)
django는 2가지 응답이 있다고 하였습니다. HttpResponse 그리고 Http404 입니다. 다음으로는 에러가 발생하는 경우 Http404를 이용하여 처리해보도록 하겠습니다.
polls/views.py
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})
위 대신 shortcut인 get_object_or_404을 사용해보자 (polls/views.py)
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})
shortcut을 사용하면 간단하게 처리 할 수 있습니다. django는 정형화 된 작업은 shortcut을 제공하니 많이 참고해야겠습니다.
마지막으로 url에서 지정한 name을 이용하여 template는 하드코딩을 없에고 다음과 같이 변경 할 수 있습니다.
변경 전
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
변경 후
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
최대한의 하드코딩을 없에고 각각의 로직을 분리해야 됩니다. 각각 수정 하였을 때 다른 부분에서 변경이 없도록 다시 말해서 영향범위를 줄이도록 코드를 작성 해야겠습니다.
'Programming > python' 카테고리의 다른 글
[python] django 튜토리얼 part 5, about automated testing (0) | 2019.01.02 |
---|---|
[python] django 튜토리얼 part 4, about form, generic view (0) | 2018.12.27 |
[python] django 튜토리얼 part 2, about db, model and admin (0) | 2018.12.21 |
[python] django 튜토리얼 part 1, about setting (0) | 2018.12.17 |
[python] pipenv dependencies problem (0) | 2018.12.10 |