Django 05편 - polls app 구현하기 2편
포스트
취소

Django 05편 - polls app 구현하기 2편

1편에서 Model을 구현했으니 이번엔 View와 Template를 구현해보자.

인수를 받는 View 만들기

  • views.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    import logging
    from django.http import HttpResponse
    
    logger = logging.getLogger('debug')
    
    
    # Create your views here.
    def index(request):
        logger.debug('polls app test.')
        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)
    
  • urls.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    from django.urls import path
    from apps.polls import views as polls_views
    
        urlpatterns = [
            path('', polls_views.index, name='index'),
            path('<int:question_id>/', polls_views.detail, name='detail'),
            path('<int:question_id>/results/', polls_views.results, name='results'),
            path('<int:question_id>/vote/', polls_views.vote, name='vote'),
        ]
        ```
    
    ![사진](/assets/img/posts/legacy/python/django-05-001.png){: .normal}
    

잘 동작한다. :)

Template 추가하기

사진

pycharm 쓸 때 template laguages를 django로 설정해주면 편함 :D

먼저, django의 template 시스템에 대한 이해가 필요하다. 공식 문서에 따르면 다음과 같다.

1
2
3
프로젝트의 TEMPLATES 설정은 Django가 어떻게 템플릿을 불러오고 렌더링 할 것인지 기술합니다.
기본 설정 파일은 APP_DIRS 옵션이 True로 설정된 DjangoTemplates 백엔드를 구성합니다.
관례에 따라, DjangoTemplates은 각 INSTALLED_APPS 디렉토리의 《templates》 하위 디렉토리를 탐색합니다.

사진

따라서 template의 파일구조는 이런식으로 구성해준다.

  • index.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    {% 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 %}
    
  • views.py

    1
    2
    3
    4
    5
    6
    7
    8
    
    from .models import Question
    from django.shortcuts import render
    
    
    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)
    

    index view를 수정해준다.

    • render()
      1
      2
      3
      4
      
      render() 함수는 request 객체를 첫번째 인수로 받고,
      템플릿 이름을 두번째 인수로 받으며,
      context 사전형 객체를 세전째 선택적(optional) 인수로 받습니다.
      인수로 지정된 context로 표현된 템플릿의 HttpResponse 객체가 반환됩니다.
      

다음으로, 데이터베이스 검색 결과가 없을 경우 404 페이지를 띄워보자.

  • detail.html

    1
    2
    3
    4
    5
    6
    
    <h1>{{ question.question_text }}</h1>
    <ul>
      {% for choice in question.choice_set.all %}
      <li>{{ choice.choice_text }}</li>
      {% endfor %}
    </ul>
    
  • views.py

    1
    2
    3
    
    def detail(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/detail.html', {'question': question})
    
    • 철학

      1
      2
      3
      4
      5
      6
      7
      8
      
      상위 계층에서 ObjectDoesNotExist 예외를 자동으로 잡아 내는 대신
      get_object_or_404() 도움 함수(helper functoin)를 사용하거나,
      ObjectDoesNotExist 예외를 사용하는 대신 Http404 를 사용하는 이유는 무엇일까요?
      
      왜냐하면, 모델 계층을 뷰 계층에 연결하는 방법이기 때문입니다.
      Django의 중요한 설계 목표는,
      약결합(loose coupling)을 관리하는 데에 있습니다.
      일부 제어된 결합이 django.shortcuts 모듈에서 도입되었습니다.
      

      상위 계층에서 예외를 자동으로 잡아 내는 java spring과는 달리 약결합 관리를 중시하는 django는 위와 같은 방법으로 shortcuts 모듈을 사용하거나 try-except문을 이용한다.

      1
      2
      3
      
      또한, get_object_or_404() 함수처럼 동작하는 get_list_or_404() 함수가 있습니다.
      get() 대신 filter() 를 쓴다는 것이 다릅니다.
      리스트가 비어있을 경우, Http404 예외를 발생시킵니다.
      

      (대충 sql에서 where절로 여러 결과를 가져와야할 경우 get_list_or_404()를 쓰면 된다는 내용)

중간 테스트

  • index 페이지

사진

  • admin 페이지에서 question 추가

사진

  • 1번째 question detail 페이지

사진

  • index 페이지

사진

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.