http://127.0.0.1:8000/home/30
에 접속하면
오류 화면이 나타난다.
현재는 settings.py의 DEBUG 항목이 True로 설정되어 있어 개발자에게 여러 정보를 알려 주는 오류 화면이 나타난다. 하지만 실제 서비스 화면에는 이런 중요한 정보가 표현되면 안 된다. 따라서 서비스를 할 때는 DEBUG 항목을 False로 설정한다.
존재하지 않은 페이지에 접속하면 오류 대신 404 페이지를 출력하도록 question_detail 함수를 수정한다. Question.objects.get(id=question_id)를 get_object_or_404(Question, pk=question_id)로 수정한다.
# home/views.py
...
from django.shortcuts import render, get_object_or_404 # render가 import 되어있다. (views.py기본 세팅)
...
def question_detail(request, question_id):
# question = Question.objects.get(id=question_id) # urls에 mapping된 question_id와 같은 것
question = get_object_or_404(Question, pk=question_id) # 404페이지 출력하기
context = { 'a_question' : question } # 위의 question를 context 변수인 a_question에 저장한다.
return render(request, 'home/question_detail.html', context)
404 페이지가 무엇인가?
웹 브라우저는 HTTP 요청을 하고, 장고는 그 요청에 응답을 한다. 보통의 경우에는 성공을 의미하는 200 응답 코드가 자동으로 반환한다. 하지만 요청하는 페이지가 없거나 서버에서 오류가 발생하면 다음과 같은 응답 코드가 반환된다.
오류코드 | 설명 |
---|---|
200 | 성공 |
500 | 서버 오류(Internal Server Error) |
장고 제네릭뷰 간단 소개
제네릭뷰(Generic View)는 목록 조회나 상세 조회처럼 특정 패턴이 있는 뷰를 작성할 때 사용하는 매우 편리한 기능이다. 하지만 장고 입문자에게는 제네릭뷰의 실행 방식이 무척 이해하기 어렵다. 만약 우리가 views.py 파일에 작성한 question_list 함수와 question_detail 함수를 제네릭뷰로 변경하면 다음과 같다.
# home/views.py
Class ListView(generic.ListView):
def get_queryset(self):
return Question.objects.order_by('-create_date')
Class DetailView(generic.DetailView):
model = Question
ListView 클래스가 question_list 함수를 대체하고 DetailView 클래스가 question_detail 함수를 대체했다고 생각하면 된다. ListView 클래스는 템플릿명이 명시적으로 지정되지 않으면 자동으로 모델명_list.html을 템플릿명으로 사용한다. 정리하자면 Question 모델을 사용하는 ListView 클래스는 question_list.html, DetailView 클래스는 question_detail.html을 템플릿명으로 사용한다. 이어서 urls.py 파일은 다음과 같이 변경한다.
# home/urls.py
from django.urls import path
from. import views
urlpattern = [
path('', views.ListView.as_view()),
path('<int:pk>/', views.DetailView.as_view()),
]
단순 모델의 목록 조회나 상세 조회는 제네릭뷰를 사용하면 매우 간편한다. 단 제네릭뷰는 복잡한 문제를 해결할 때 오히려 개발 난이도를 높이는 경우도 있으니 주의해야 한다.