Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send Custom message in Django PermissionDenied

I am using django's PermissionDenied to render 403.html whenever the user is not allowed to access any page.

There are whole lot of pages, of different type, for example, Product page, User Page, User Contact information, Owner Information.

I would like to add the custom message with PermissionDenied, that would tell the user exactly why he can not view this page. I would like to add the following dynamic message to the 403.html.

You have are trying to `View a Product (id:3094384)` while having a `Trail` account. You are not authorized to view this product. 

And

 You have are trying to `View a Customer (id:48)` which is Private. You are not authorized to view this User. 

and so on.

here is my code

elif role.id == Project.ROLE_SALES and not project.sales_person_id == user_id:
            raise PermissionDenied

html

<body class="error-page">

<!--  content -->
<section>
    <div class="error403">
        <h1>403</h1>
    </div>
    <p class="description">Oops! Request forbidden...</p>

    <p>Sorry, it appears the page you were looking for is forbidden and not accessible. If the problem persists, please
        contact web Administrator.</p>


# HERE I WANT TO SHOW DYNAMIC MESSAGE. 



    <a href="{{ request.META.HTTP_REFERER }}" class="btn btn-danger403 btn-primary btn-large" >
        Go Back </a>
{{ except }}
</section>



<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
</body>

Possibility

raise PermissionDenied("Custom message")

Or

Pass a context to PermissionDenied?

Suggestions.

like image 399
A.J. Avatar asked Aug 19 '14 06:08

A.J.


People also ask

How to persist email notifications across Django sessions?

Therefore it requires Django’s contrib.sessions application. This class stores the message data in a cookie (signed with a secret hash to prevent manipulation) to persist notifications across requests. Old messages are dropped if the cookie data size would exceed 2048 bytes.

Does Django support session-based messaging?

For this, Django provides full support for cookie- and session-based messaging, for both anonymous and authenticated users. The messages framework allows you to temporarily store messages in one request and retrieve them for display in a subsequent request (usually the next one).

What is @permissiondenied exception in Django?

PermissionDenied exception can be used to implement nested permission classes where child permission checks should not proceed when the parent permission check fails. Django REST framework is a robust framework to write REST APIs and is highly customizable.

How to restrict user permission in Django REST framework?

Django REST framework is a powerful and flexible toolkit for building Web APIs in the Django framework. Django REST framework comes with a robust permission manager which can be used to restrict user permission per view or per-object basis. To use the permission check you need to add the specific permission to the permission_classes.


3 Answers

This answer is probably arriving very late for you. But here it is. You can use this in your Django code:

raise PermissionDenied("Custom message")

And then display the custom message using below snippet in the 403.html template:

{% if exception %}
  <p>{{ exception }}</p>
{% else %}
  <p>Static generic message</p>
{% endif %}

The message string passed to 'PermissionDenied' is available in template context as explained in Django documentation - https://docs.djangoproject.com/en/1.10/ref/views/#http-forbidden-view

like image 167
kvrao127 Avatar answered Oct 22 '22 06:10

kvrao127


I came across the same issue and resolved it using the Django messages framework to pass a custom message to the template.

https://docs.djangoproject.com/en/1.8/ref/contrib/messages/

My specific example:

from django.contrib import messages
...
messages.error(request, 'The submission deadline has passed.')
raise PermissionDenied

The messages can then be output in the template as described in the documentation.

like image 2
Grant Anderson Avatar answered Oct 22 '22 08:10

Grant Anderson


You can try like this:

class SomeException(Exception):
    message = 'An error occurred.'

    def __init__(self, message):
        self.message = message

    def __str__(self):
        return repr(self.message)

#usage
 raise SomeException("Hello, you have an exception here")

Another way of sending a message to template is like:

if not request.user.is_staff: #or your condition
   context['flash_message']= "permission error occurred"
   retrun render_to_response('template.html', context)

# template
<!-- I am using bootstrap here -->
<div class="alert alert-{{ flash_message_type }} flash_message hide">
    {{ flash_message | safe }}
</div>

<script>
...
if($.trim($(".flash_message").html()) != ''){
        $(".flash_message").slideDown();
        setTimeout(function(){
            $(".flash_message").slideUp();
        }, 5000);
    };
</script>
like image 1
ruddra Avatar answered Oct 22 '22 06:10

ruddra