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の下に存在する必要があります。
  • 必要に応じて、handler403handler400handler500を手動で登録して特定のビューに接続することもできます。

まとめ

項目 内容
raise Http404使用時 404.htmlテンプレート自動レンダリング
get_object_or_404() オブジェクトがなければ自動で404発生
テンプレート名 必ず404.html403.htmlなどの固定名を使用
ディレクトリ条件 TEMPLATES['DIRS']またはAPP_DIRS内部でなければならない
DEBUG条件 DEBUG = Falseのときにのみユーザーテンプレートが適用される
高度な使用 handler404handler500などで特定のビューを接続可能