-
[Django tutorial] django official tutorial part3 정리Software, Computer Science/Django, Flask 2020. 2. 3. 21:29
Part 3
django에서의 view는 특정 기능과 알고리즘을 수행하며 template을 제공해 주는 역할을 하는 웹페이지이자 모듈이다. polls 앱 기준으로 다음과 같은 4개의 view를 구성해 볼 수 있다.(실제 MVC 디자인 패턴에서 Controller에 해당한다, 또한 View는 django에서 template이나 FE단의 페이지가 될 수 있다)
- 질문 "index" page : 질문 표시
- 질문 "detail" page : 질문 및 투표 서식 표시
- 질문 "results" page : 특정 질문에 대한 결과 표시
- 투표 기능 : 질문에 대해 투표할 수 있는 기능
from django.shortcuts import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the polls index.") 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)
URL 패턴 또한 URLConf를 통해 간결하게 만들 수 있으며 해당 패턴을 view에 연결 시켜 주기도 한다.(URL dispatcher 참고)
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'), ]
urlpatterns 리스트 안 두번째 path 메소드를 간단히 설명하면 views.py 안에 있는
detail()
을 통하여 URL에 입력한 ID를 출력하게 되어 있고 해당 url을 통하여 투표 서식을 볼 수 있다. 결과적으로detail()
엔 다음과 같이 값이 전달된다detail(request=<HttpRequest object>, question_id=34)
view가 기능 할 수 있게끔 구성해보기
view가 어떤 식으로 동작하는지 템플릿의 연결관계와 더불어 튜토리얼에서 설명하고 있다. 이 파트에선 그 과정을 요약해서 한번에 정리한다.
먼저 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 %}
원래는 아래와 같이 template을 직접 load 해서 HttpResponse 객체를 리턴하게끔 되어 있지만 django에선 이걸 축약해서 render 메소드를 통해 구현하게 끔 되어 있다.
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))
404에러를 일으킬 때의 예외처리 또한 아래와 같은 예로 구성이 되어 있는데
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})
이 또한 shortcuts 모듈 안에 있는 get_object_or_404 메소드를 통해 간단히 구현할 수 있다.
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})
요약하면 views.py에서 복잡한 처리 과정이 있는데 shortcuts 모듈 안에 있는 메소드들이 간단히 구현하게 해준다는 것이다.
템플릿 문법 또한 기존에 html/css와는 다른 모습에 이질적이지만 어느정도 잘 활용할 줄 안다면 url경로의 의존성을 줄이거나 반복문이나 조건문의 사용을 통해 긴 코드도 짧게 줄일 수 있는 장점이 있다.
<!-- polls/templates/polls/detail.html --> <h1>{{ question.question_text }}</h1> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul>
템플릿 문법을 이용하여 하드코딩된 url 제거하는 방법 예제
{% if latest_question_list %} <ul> {% for question in latest_question_list %} <!-- <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li> --> <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
URL의 이름공간(namespace) 정하는 방법
실제 django 프로젝트는 앱이 몇개라도 추가가 될 수 있다. 그렇다면 그 많은 app들 중에 URL을 어떻게 구분할까 ? 다시 말해 polls라는 앱에 detail이 있을 수도 있고 같은 프로젝트 내에 blog라는 앱에도 detail이라는 view가 있을 수도 있다. 이를 구분하기 위해 URLConf에 namespace를 추가한다.
# polls/urls.py from django.urls import path from . import views app_name = 'polls' urlpatterns = [ path('', views.index, name='index'), path('<int:question_id>/', views.detail, name='detail'), path('<int:question_id>/results/', views.results, name='results'), path('<int:question_id>/vote/', views.vote, name='vote'), ]
이에따라 polls/index.html의 템플릿의 기존 내용을 아래와 같이 수정한다(어디에서 온 view인지 명시)
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
Reference
'Software, Computer Science > Django, Flask' 카테고리의 다른 글
[Django] 간단한 endpoint를 django 에서 구현해 보기 (0) 2020.02.07 [Django] Django MVT 패턴에 관한 내용 정리, url이 분석되는 순서 (0) 2020.02.05 [Django tutorial] django official tutorial part4 정리 (0) 2020.02.03 [Django tutorial] django official tutorial part2 정리 (0) 2020.02.03 [Django tutorial] django official tutorial part1 정리 (0) 2020.02.03 댓글