在Django開發中,我們經常希望使用像 raise Http404("Page not found.") 這樣的代碼來顯示自定義的404頁面。
本篇文章將實用地整理 404錯誤的產生原因模板連接方法,以及 403/500錯誤的處理方式

Custom 404 error page illustration for Django


1. 觸發404錯誤的常見方法

我們對Django中發生404錯誤的情況進行了分類,可能有以下四種情況。

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 等連接特定視圖