Tagged: error

Django: how to make customized error pages (404, 500, etc.)

When you want to make custom error pages, it’s very simple … once you know how to do it!
The documentation is not very clear on this point…

Here is a summary of my experience, to make custom error pages (404, 500, etc.).
You should first know that errors are called functions (= you cannot do this via generic views).
Then the documentation gives an example, but it’s not enough.
Thanks to Django code shortcuts, you have the function render() to which you can pass a template and a context (= therefore variables).
I used this to create a dictionary that contains the errors, and pass them in a context (= dictionary) with the title and content keys.


Here is the view code that displays “cleanly” the error:

from django.shortcuts import render
from django.utils.translation import gettext_lazy as _
VIEW_ERRORS = {
    404: {'title': _("404 - Page not found"),
          'content': _("A 404 Not found error indicates..."), },
    500: {'title': _("Internal error"),
          'content': _("A 500 Internal error means..."), },
    403: {'title': _("Permission denied"),
          'content': _("A 403 Forbidden error means ..."), },
    400: {'title': _("Bad request"),
          'content': _("A 400 Bad request error means ..."), }, }
def error_view_handler(request, exception, status):
    return render(request, template_name='errors.html', status=status,
                  context={'error': exception, 'status': status,
                           'title': VIEW_ERRORS[status]['title'],
                           'content': VIEW_ERRORS[status]['content']})
def error_404_view_handler(request, exception=None):
    return error_view_handler(request, exception, 404)
def error_500_view_handler(request, exception=None):
    return error_view_handler(request, exception, 500)
def error_403_view_handler(request, exception=None):
    return error_view_handler(request, exception, 403)
def error_400_view_handler(request, exception=None):
    return error_view_handler(request, exception, 400)


Once the views are done, you have to go to the main declaration of your views. This is the urls.py file at the root of your project. If you put the code elsewhere, it will be ignored.

In this file, declare your functions that handle the errors:

handler404 = 'app.views.errors.error_404_view_handler'
handler500 = 'app.views.errors.error_500_view_handler'
handler403 = 'app.views.errors.error_403_view_handler'
handler400 = 'app.views.errors.error_400_view_handler'

And finally, in your templates, create a file errors.html in which you will code your HTML page which shows the error in a clean way.
Note that you have in the context the variables {{ title }} and {{ content }} which are respectively the title and the detail of the error.

Now, how, in “development” mode, test these pages? In practice you cannot, because in development mode, an error displays debugging information, and not your pages!

The solution: make a URL that “simulates” the error. Example with 404: add in your main url’s file: path('404/', error_404_view_handler), and then display the appropriate URL in your browser, ie http://localhost:8000/404/ and you will see the error!

I’m sorry my english is always perfectible, if I’ve made some mistakes, please let a comment and I’ll correct this post. Thanks a lot!