12

My question is simple, how do I display a custom error page for HTTP status 405 (method not allowed) in Django when using the @require_POST decorator?

I'm using the django.views.decorators.http.require_POST decorator, and when the page is visited by GET request, the console shows a 405 error, but the page is just blank (not even a Django error page). How do I get Django to display a custom and/or default error page for this kind of error?

EDIT: It's worth mentioning that I've tried putting a 404.html, 500.html and 405.html page in my templates folder - but that does not help either. I have also varied between DEBUG = True and False, to no avail.

Martin Brown
  • 22,802
  • 13
  • 71
  • 107
Herman Schaaf
  • 39,417
  • 19
  • 92
  • 137

3 Answers3

14

You have to write custom Django middleware. You can start with this one and extend it to check if 405.html file exists and so on:

from django.http import HttpResponseNotAllowed
from django.template import RequestContext
from django.template import loader


class HttpResponseNotAllowedMiddleware(object):
    def process_response(self, request, response):
        if isinstance(response, HttpResponseNotAllowed):
            context = RequestContext(request)
            response.content = loader.render_to_string("405.html", context_instance=context)
        return response

Check docs if you don't know how to install middleware:

http://docs.djangoproject.com/en/dev/topics/http/middleware/

You can also check this article:

http://mitchfournier.com/2010/07/12/show-a-custom-403-forbidden-error-page-in-django/

Vladimir Mihailenco
  • 3,271
  • 1
  • 21
  • 37
  • Thanks - it seems so obvious now! But quite a lot more trouble than I expected. – Herman Schaaf Jan 09 '11 at 17:43
  • This was a helpful response but it no longer worked for me on Django 1.11. I had to use `response.content = loader.render_to_string("405.html", request=request)` and no longer could use (or had to use) the context. – jonespm Apr 13 '19 at 02:31
0

If you look into the documentation and the source code of django.views.defaults you see that only 404 and 500 errors are supported in a way that you only have to add the 404.html resp. 500.html to your templates directory.

In the doc. you can also read the following

Returning HTTP error codes in Django is easy. There are subclasses of HttpResponse for a number of common HTTP status codes other than 200 (which means "OK"). You can find the full list of available subclasses in the request/response documentation.

Thus if you want to return a 405 error, you have to use the HttpResponseNotAllowed class

An example

Thomas Kremmel
  • 13,615
  • 21
  • 104
  • 169
  • I'm afraid you're not answering the question - the problem isn't returning a 405 status - the problem is displaying a template for that response while using the @require_POST decorator. – Herman Schaaf Jan 06 '11 at 13:06
  • You are right, missed the information you are using the decorator. – Thomas Kremmel Jan 06 '11 at 13:21
0

I'm not sure that's possible. Perhaps you should consider filing a bug report.

PeanutButterJelly
  • 907
  • 1
  • 8
  • 11
  • Well, we now know it is possible. But it is anything but as simple as adding a page for 404 and 500. Considering there's a built-in decorator for @require_POST etc, one would expect it to be easier. – Herman Schaaf Jan 09 '11 at 17:42