yuechen
yuechen

Reputation: 221

Django 404 pages return 200 status code

I'm going through the Django tutorial and am on part 5: Testing. I run into the problem where I'm using the DetailView and ListView "shortcut" views to factor out code (as suggested by the tutorial), but when a 404 page is displayed, a 200 status code is returned instead. Am I doing something wrong? The tutorial says the status code should be 404.

Thanks!

Upvotes: 5

Views: 2872

Answers (2)

Fabio Nolasco
Fabio Nolasco

Reputation: 7492

You need to define the Http header to have a 404 status.

return HttpResponse(content=template.render(context), content_type='text/html; charset=utf-8', status=404)

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.

If you are trying to make a custom 404 page, 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. =)

Upvotes: 5

trinchet
trinchet

Reputation: 6933

You can

return HttpResponseNotFound(render_to_string('404.html')) 

instead.

Upvotes: 0

Related Questions