While developing in Django, you often want to show a custom 404 page using code like raise Http404("Page not found.").
In this post, I will practically organize the causes of 404 errors, how to connect templates, and handling 403/500 errors.

Custom 404 error page illustration for Django


1. Common Ways to Raise a 404 Error

I have classified the situations in which a 404 error occurs in Django, and I believe there are about four main cases.

1. raise Http404("Description")

This is the most basic method to explicitly raise a 404 error.

from django.http import Http404

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

2. get_object_or_404()

This is a commonly used shortcut function in Django. It automatically raises a 404 error if the object does not exist.

from django.shortcuts import get_object_or_404

post = get_object_or_404(Post, pk=pk)

3. Exception Handling After Using Model.objects.get()

In this case, you also need to manually raise a 404 error.

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. When URLConf or View Does Not Exist

Unlike the previous cases, this is not a 404 raised intentionally by the developer, but when a requester accesses a non-existent URL, Django internally raises a 404 automatically.


2. How to Customize

Prerequisites

  1. The template name must be 404.html.
  2. The following items must be set in settings.py:
  3. DEBUG = False
  4. ALLOWED_HOSTS must be set
  5. The 404.html template must be in a location where Django can find it.

Template Locations

Location Description
project_root/templates/404.html The most common and stable location
app_name/templates/404.html Possible, but requires APP_DIRS = True
app_name/templates/app_name/errors/404.html Not automatically recognized, requires handler404 settings

Example of Manual Connection via 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. Can 403 and 500 Errors Also Be Customized?

✔ Django allows customization of the following error pages as templates, in addition to 404:

Error Code Default Template Name Description
403 403.html Permission Denied
404 404.html Not Found
500 500.html Internal Server Error
400 400.html Bad Request

✔ The Basic Conditions Are the Same

  • Templates will only apply if DEBUG = False.
  • Templates must exist under TEMPLATES['DIRS'] or APP_DIRS=True.
  • If necessary, handler403, handler400, and handler500 can be manually registered to link to specific views.

Summary

Item Content
When using raise Http404 Automatically renders 404.html template
get_object_or_404() Automatically raises 404 if object is not found
Template Name Must use fixed names like 404.html, 403.html, etc.
Directory Conditions Must be within TEMPLATES['DIRS'] or APP_DIRS
DEBUG Condition User templates are only applied when DEBUG = False
Advanced Use Can connect to specific views using handler404, handler500, etc.