[Solved]-How to display a custom error page for HTTP status 405 (method not allowed) in Django when using @require_POST



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:


You can also check this article:



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


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


I landed here in 2022. The above accepted answer is not working for me. I use django rest framework. My sollution was to create a middleware with


from django.http import HttpResponse
from django.template import loader

class HttpResponseNotAllowedMiddleware:
    def __init__(self, get_response):
    self.get_response = get_response
    # One-time configuration and initialization.

def __call__(self, request):
    # Code to be executed for each request before
    # the view (and later middleware) are called.

    response = self.get_response(request)

    # Code to be executed for each request/response after
    # the view is called.
    if response.status_code == 405:
        context = {}
        template = loader.get_template('app/405.html')
        return HttpResponse(template.render(context, request))

    return response

then install it by adding this to settings


the 405.html template is just a plain not allowed text

πŸ‘€John Anderton

Leave a comment