Django, creating a custom 500/404 error page

Zac picture Zac · Jul 15, 2013 · Viewed 165.5k times · Source

Following the tutorial found here exactly, I cannot create a custom 500 or 404 error page. If I do type in a bad url, the page gives me the default error page. Is there anything I should be checking for that would prevent a custom page from showing up?

File directories:

mysite/
    mysite/
        __init__.py
        __init__.pyc
        settings.py
        settings.pyc
        urls.py
        urls.pyc
        wsgi.py
        wsgi.pyc
    polls/
        templates/
            admin/
                base_site.html
            404.html
            500.html
            polls/
                detail.html
                index.html
        __init__.py
        __init__.pyc
        admin.py
        admin.pyc
        models.py
        models.pyc
        tests.py
        urls.py
        urls.pyc
        view.py
        views.pyc
    templates/
    manage.py

within mysite/settings.py I have these enabled:

DEBUG = False
TEMPLATE_DEBUG = DEBUG

#....

TEMPLATE_DIRS = (
    'C:/Users/Me/Django/mysite/templates', 
)

within mysite/polls/urls.py:

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
    url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)

I can post any other code necessary, but what should I be changing to get a custom 500 error page if I use a bad url?

Edit

SOLUTION: I had an additional

TEMPLATE_DIRS

within my settings.py and that was causing the problem

Answer

Aaron Lelevier picture Aaron Lelevier · Jul 13, 2014

Under your main views.py add your own custom implementation of the following two views, and just set up the templates 404.html and 500.html with what you want to display.

With this solution, no custom code needs to be added to urls.py

Here's the code:

from django.shortcuts import render_to_response
from django.template import RequestContext


def handler404(request, *args, **argv):
    response = render_to_response('404.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 404
    return response


def handler500(request, *args, **argv):
    response = render_to_response('500.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 500
    return response

Update

handler404 and handler500 are exported Django string configuration variables found in django/conf/urls/__init__.py. That is why the above config works.

To get the above config to work, you should define the following variables in your urls.py file and point the exported Django variables to the string Python path of where these Django functional views are defined, like so:

# project/urls.py

handler404 = 'my_app.views.handler404'
handler500 = 'my_app.views.handler500'

Update for Django 2.0

Signatures for handler views were changed in Django 2.0: https://docs.djangoproject.com/en/2.0/ref/views/#error-views

If you use views as above, handler404 will fail with message:

"handler404() got an unexpected keyword argument 'exception'"

In such case modify your views like this:

def handler404(request, exception, template_name="404.html"):
    response = render_to_response(template_name)
    response.status_code = 404
    return response