Django에서 개발을 하다 보면 raise Http404("Page not found.")와 같은 코드를 통해 사용자 정의 404 페이지를 보여주고 싶을 때가 많습니다.
이 글에서는 404 에러 발생 원인, 템플릿 연결 방법, 그리고 403/500 에러 처리 방식까지 실용적으로 정리해 보겠습니다.

Custom 404 error page illustration for Django


1. 404 에러를 발생시키는 대표적인 방법들

Django 에서 404 에러가 발생하는 경우를 분류해봤는데, 아마도 아래의 4가지 정도가 아닐까 생각합니다.

1. raise Http404("설명")

직접 명시적으로 404 에러를 발생시키는 가장 기본적인 방법입니다.

from django.http import Http404

def my_view(request):
    if not condition:
        raise Http404("Page not found.")

2. get_object_or_404()

Django에서 자주 사용하는 단축 함수입니다. 객체가 없을 경우 자동으로 404를 발생시킵니다.

from django.shortcuts import get_object_or_404

post = get_object_or_404(Post, pk=pk)

3. Model.objects.get() 사용 후 예외 처리

이 경우에도 수동으로 404를 발생시켜야 합니다.

from django.http import Http404
from django.core.exceptions import ObjectDoesNotExist

try:
    post = Post.objects.get(pk=pk)
except ObjectDoesNotExist:
    raise Http404("Post not found.")

4. URLConf나 View가 존재하지 않을 때

위 1~3번과는 달리 개발자가 의도적으로 발생시킨 404는 아니자만, 요청자가 존재하지 않는 URL로 접근할 경우 Django가 내부적으로 자동으로 404를 발생시킵니다.


2. 커스터마이징 방법

필수 조건

  1. 템플릿 이름은 반드시 404.html이어야 합니다.
  2. settings.py에서 아래 항목이 설정되어 있어야 합니다:
  3. DEBUG = False
  4. ALLOWED_HOSTS 설정됨
  5. 404.html 템플릿은 Django가 찾을 수 있는 위치에 있어야 합니다.

템플릿 위치

위치 설명
프로젝트 루트/templates/404.html 가장 일반적이고 안정적인 위치
앱명/templates/404.html 가능하지만 APP_DIRS = True 조건 필요
앱명/templates/앱명/errors/404.html 자동 인식되지 않음, handler404 설정 필요

handler404를 통한 수동 연결 예시

# views.py
def custom_404_view(request, exception):
    return render(request, 'myapp/errors/404.html', status=404)

# urls.py
handler404 = 'myapp.views.custom_404_view'

3. 403, 500 에러도 커스터마이징 가능할까?

✔ Django는 404 외에도 다음 에러 페이지도 템플릿으로 커스터마이징 가능합니다:

에러 코드 기본 템플릿 이름 설명
403 403.html 권한 없음 (Permission Denied)
404 404.html 페이지를 찾을 수 없음 (Not Found)
500 500.html 서버 내부 오류 (Internal Server Error)
400 400.html 잘못된 요청 (Bad Request)

✔ 기본 조건은 동일합니다

  • DEBUG = False여야 템플릿이 적용됩니다.
  • 템플릿은 TEMPLATES['DIRS'] 또는 APP_DIRS=True 경로 아래 존재해야 합니다.
  • 필요한 경우, handler403, handler400, handler500을 수동으로 등록해서 특정 뷰에 연결할 수도 있습니다.

요약 정리

항목 내용
raise Http404 사용 시 404.html 템플릿 자동 렌더링
get_object_or_404() 객체가 없으면 자동으로 404 발생
템플릿 이름 반드시 404.html, 403.html 등 고정된 이름 사용
디렉토리 조건 TEMPLATES['DIRS'] 또는 APP_DIRS 내부여야 함
DEBUG 조건 DEBUG = False일 때만 사용자 템플릿이 적용됨
고급 사용 handler404, handler500 등으로 특정 뷰 연결 가능