Django 입문 404에러 일으키기, 템플릿 시스템 활용하기

1c2·2023년 7월 23일
0

Django

목록 보기
7/12

404 에러 일으키기

현재 view의 detail함수는 question_id에 따라서 화면을 보여준다. 만약 question_id가 없는 경우에는 404에러를 띄우도록 하겠다.

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})

일단 예제를 동작하기 위해 detail.html에 다음과 같이 추가하였다.

polls/templates/polls/detail.html

{{question}}

http://127.0.0.1:8000/polls/1/ 에 접속하는 경우 다음과 같은 화면이 출력된다.

하지만 http://127.0.0.1:8000/polls/2/ 에 접속하면

다음과 같이 404에러를 발생시킨다.
try catch문을 사용하는 것 대신 get_object_or_404를 사용할 수 있다.

polls/views.py

from django.shortcuts import get_object_or_404, render

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, "polls/detail.html", {"question": question})

템플릿 시스템 활용하기

이번에는 한 question에 대해 이를 외래키로 갖는 다른 choice들을 활용해 볼 것이다.

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>

detail.html을 다음과 같이 수정하였다. question의 question_text와 question을 외래키로 가지는 choice들을 모두 출력한다.

admin을 사용해서 choice들을 만들어보자.

polls/admin.py

from django.contrib import admin

from .models import Question, Choice

admin.site.register(Question)
admin.site.register(Choice)

admin에 다음과 같이 choice에 대한 권한을 추가한다.

이제 관리자 페이지에서 다음과 같이 choice를 추가할 수 있다. choice 1, 2, 3을 추가해주자.

다음과 같이 choice들이 출력되는 것을 확인할 수 있다.

템플릿에서 하드코딩된 URL 제거하기

polls/index.html을 보게되면

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

이렇게 URL이 하드코딩 되어있다. 이렇게 되면 URL 변경시 URL이 있는 템플릿 코드들을 변경해야 한다. 장고에서는 url마다 name을 명시할 수 있기 때문에 다음과 같이 변경하면 수정의 영향에서 자유로워 진다.
URLconf에 이름공간(namespace)를 추가한다. polls/urls.py에 app_name을 추가하여 어플리케이션의 이름공간을 설정한다.

polls/url.py

from django.urls import path

from . import views
app_name = 'polls'
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"),
]

polls/index.html

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

다음과 같이 index.html을 수정할 수 있다.

0개의 댓글