Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Django 404 error

I have a 404.html page, but in some cases I want to be able to send a json error message (for 404 and 500, etc.). I read the following page:

https://docs.djangoproject.com/en/dev/topics/http/views/#the-404-page-not-found-view

Is there any sort of example that shows the implementation? I have it in my urls.py but it's not being picked up in the event of an error.

like image 902
KVISH Avatar asked Jul 03 '12 00:07

KVISH


3 Answers

In addition to the previous answer, it is important to say that the views.py should return a HttpResponse with a 404 status in the http header. It is important to inform the search engines that the current page is a 404. Spammers sometimes creates lots of urls that could seem that would lead you to some place, but then serves you another content. They frequently make lots of different addresses serve you almost the exact same content. And because it is not user friendly, most SEO guide lines penalize that. So if you have lots of addresses showing the same pseudo-404 content, it could not look good to the crawling systems from the search websites. Because of that you want to make sure that the page you are serving as a custom 404 has a 404 status. So here it is a good way to go:

Into your application's urls.py add:

# Imports
from django.conf.urls.static import static
from django.conf.urls import handler404
from django.conf.urls import patterns, include, url
from yourapplication import views

##
# Handles the URLS calls
urlpatterns = patterns('',
    # url(r'^$', include('app.homepage.urls')),
)

handler404 = views.error404

Into your application's views.py add:

# Imports
from django.shortcuts import render
from django.http import HttpResponse
from django.template import Context, loader


##
# Handle 404 Errors
# @param request WSGIRequest list with all HTTP Request
def error404(request):

    # 1. Load models for this view
    #from idgsupply.models import My404Method

    # 2. Generate Content for this view
    template = loader.get_template('404.htm')
    context = Context({
        'message': 'All: %s' % request,
        })

    # 3. Return Template for this view + Data
    return HttpResponse(content=template.render(context), content_type='text/html; charset=utf-8', status=404)

The secret is in the last line: status=404

Hope it helped!

I look forward to see the community inputs to this approach. =)

like image 114
Fabio Nolasco Avatar answered Oct 16 '22 13:10

Fabio Nolasco


This worked for me:

from django.conf.urls import patterns, include, url
from django.views.static import * 
from django.conf import settings
from django.conf.urls.defaults import handler404, handler500
from app.views import error

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'app.views.home', name='home'),
)

handler404 = error.error_handler
handler500 = error.error_handler

You can make it do anything as you wish when going to that controller.

like image 38
KVISH Avatar answered Oct 16 '22 11:10

KVISH


Basics:

To define custom view for handling 404 errors, define in the URL config, a view for handler404, like handler404 = 'views.error404'

Apart from the basics, some things to note about (custom 404 views):

  1. It will be enabled only in Debug=False mode.
  2. And more ignored one, across most answers (and this this stuck my brains out).

    The 404 view defaults to

    django.views.defaults.page_not_found(request, exception, template_name='404.html')

    Notice the parameter exception

    This was causing a 404 to 500 redirect from within def get_exception_response(self, request, resolver, status_code, exception) function defined in core.handlers.base since it could not find the parameter exception

like image 31
Gaurav Toshniwal Avatar answered Oct 16 '22 12:10

Gaurav Toshniwal