214

I'd like to do the following:

raise HttpResponseForbidden()

But I get the error:

exceptions must be old-style classes or derived from BaseException, not HttpResponseForbidden

How should I do this?

Vini.g.fer
  • 11,093
  • 15
  • 55
  • 83
ocoutts
  • 4,298
  • 7
  • 25
  • 30

4 Answers4

446

if you want to raise an exception you can use:

from django.core.exceptions import PermissionDenied

def your_view(...):
    raise PermissionDenied()

It is documented here :

https://docs.djangoproject.com/en/stable/ref/views/#the-403-http-forbidden-view

As opposed to returing HttpResponseForbidden, raising PermissionDenied causes the error to be rendered using the 403.html template, or you can use middleware to show a custom "Forbidden" view.

andyhasit
  • 12,671
  • 6
  • 46
  • 50
Chris
  • 11,972
  • 5
  • 18
  • 22
  • You can still provide middleware with a process_exception method and render your view from there. – deterb May 08 '14 at 19:32
  • 2
    Can we add a custom message in PermissionDenied? – A.J. Aug 19 '14 at 05:59
  • 2
    Jack, yes you can -- do something like: raise PermissionDenied("No logged in user") – Mark Chackerian Oct 08 '14 at 13:43
  • 2
    Not sure if it matters, but the docs say `throw PermissionDenied` not as a function call, without the `()` at the end. – Fydo Nov 14 '14 at 15:05
  • 2
    What's the advantage of using this over HttpResponseForbidden? – Flimm Jan 06 '16 at 16:41
  • 3
    @Flimm: This automatically triggers 403 at middleware level, allowing you to show your custom "Forbidden" view. – Damaged Organic Mar 08 '16 at 15:03
  • 1
    @MarkChackerian any idea of `PermissionDenied` in Django 1.6. I created a custom 403.html . How to retrieve the custom message in html ? . `raise PermissionDenied("custom message")` dont show my custom message – Manuj Rastogi Jan 06 '17 at 12:07
  • Using this in an admin view and still getting 500 instead of 403. Any idea what I could be doing wrong? – Ariel Jan 30 '19 at 11:00
212

Return it from the view as you would any other response.

from django.http import HttpResponseForbidden

return HttpResponseForbidden()
Maxime Lorant
  • 31,821
  • 17
  • 84
  • 96
Ignacio Vazquez-Abrams
  • 740,318
  • 145
  • 1,296
  • 1,325
  • 40
    Why does there exists an exception class `Http404` but not `Http403`? Why the inconsistency? – Flimm Jan 28 '16 at 13:34
  • @Flimm http://stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses I'm not sure about Django, but Django REST Framework has: from rest_framework import status status.HTTP_403_FORBIDDEN 403 – David Watson Mar 04 '16 at 18:35
  • 24
    Actually using `raise PermissionDenied` has the advantage of letting you show your custom 403 view – gdvalderrama Jul 08 '16 at 09:01
12

You can optionally supply a custom template named "403.html" to control the rendering of 403 HTTP errors.

As correctly pointed out by @dave-halter, The 403 template can only be used if you raise PermissionDenied

Below is a sample view used to test custom templates "403.html", "404.html" and "500.html"; please make sure to set DEBUG=False in project's settings or the framework will show a traceback instead for 404 and 500.

from django.http import HttpResponse
from django.http import Http404
from django.core.exceptions import PermissionDenied


def index(request):

    html = """
<!DOCTYPE html>
<html lang="en">
  <body>
    <ul>
        <li><a href="/">home</a></li>
        <li><a href="?action=raise403">Raise Error 403</a></li>
        <li><a href="?action=raise404">Raise Error 404</a></li>
        <li><a href="?action=raise500">Raise Error 500</a></li>
    </ul>
  </body>
</html>
"""

    action = request.GET.get('action', '')
    if action == 'raise403':
        raise PermissionDenied
    elif action == 'raise404':
        raise Http404
    elif action == 'raise500':
        raise Exception('Server error')

    return HttpResponse(html)
Mario Orlandi
  • 5,261
  • 24
  • 26
4

Try this Way , sending message with Error

from django.core.exceptions import PermissionDenied
raise PermissionDenied("You do not have permission to Enter Clients in Other Company, Be Careful")
Saad Mirza
  • 1,014
  • 12
  • 21