ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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) unchanged

     

     

    index() 뷰 하나를 호출했을 때, 

    시스템에 저장된 최소한 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 part3

    '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
Designed by Tistory.