This article shows how to customize 404 (not found) page on your Django website.
In production mode (DEBUG = False), Django displays the default 404 page if the resource does not exist. When you raise Http404
exception in a view, Django invokes a special view which is added to handle 404 errors. By default, the Django handler404 view is django.views.defaults.page_not_found()
. This view either displays a “Not Found” message or renders the template 404.html
if you added it to your root template directory.
Let's assume the default 404 page does not fit our needs. So we need to add a new template to your root template directory and name it 404.html
.
{% extends 'base.html' %}
{% load static %}
{% block title %} Posts {% endblock %}
{% block content %}
<div class="mt-3">
<div class="container">
<h3>Not Found</h3>
</div>
</div>
{% endblock %}
In our case, the root template directory is defined in ‘DIRS’
key: 'DIRS': [os.path.join(BASE_DIR, 'templates')]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Next, to test it add a view and call it post_detail
, which raises the Http404
exception if the post is not found with the given slug.
def post_detail(request, slug):
try:
post = models.Post.objects.get(slug=slug)
except models.Post.DoesNotExist:
raise Http404
return render(
request,
'blog/post-detail.html',
context={'post': post}
)
If you are running the website in debug mode (DEBUG = True
in settings.py) it does not render a 404.html
template, instead, it renders URLconf
with some debug information.
To see the custom 404 page in action change DEBUG
to False
and got to the non-existing page or /post/<non-existing-slug>. You should now see the custom 404 page: