Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can make Django permission_required decorator not to redirect already logged-in users to login page, but display some message

How can make Django permission_required decorator not to redirect already logged-in users to login page, but display some message like Insufficient permissions?

Thank you.

like image 682
dsmilkov Avatar asked Aug 09 '09 10:08

dsmilkov


People also ask

How to logout a user in Django?

To log out a user who has been logged in via django.contrib.auth.login() , use django.contrib.auth.logout() within your view. It takes an HttpRequest object and has no return value.

How to create user authentication in Django?

In a nutshell, these four commands create a new Django project named src, enter the project, create a new app, mysite, inside the src project, then create a SQLite database for the project named db. sqlite3. Also be sure to include the mysite app inside src/settings.py. INSTALLED_APPS = [ 'src', 'django.

Has permission in Django?

Overview. Django provides an authentication and authorization ("permission") system, built on top of the session framework discussed in the previous tutorial, that allows you to verify user credentials and define what actions each user is allowed to perform.


4 Answers

A quick and dirty solution would be to write your own decorator to do this. Something like this:

decorator_with_arguments = lambda decorator: lambda *args, **kwargs: lambda func: decorator(func, *args, **kwargs)

@decorator_with_arguments
def custom_permission_required(function, perm):
    def _function(request, *args, **kwargs):
        if request.user.has_perm(perm):
            return function(request, *args, **kwargs)
        else:
            request.user.message_set.create(message = "What are you doing here?!")
            # Return a response or redirect to referrer or some page of your choice
    return _function

You can then decorate your view thus:

@custom_permission_required('my_perm')
def my_view(request, *args, **kwargs):
    #Do stuff
like image 144
Manoj Govindan Avatar answered Oct 16 '22 18:10

Manoj Govindan


Since django 1.4 permission_required has a raise_exception parameter that you can set to True to have an unauthorized PermissionDenied exception raised

Eg. to give an exemple on a Class Based View:

from django.contrib.auth.decorators import permission_required
...

class MyView(TemplateView):

    @method_decorator(permission_required('can_do_something', raise_exception=True))
    def dispatch(self, *args, **kwargs):
        return super(MyView, self).dispatch(*args, **kwargs)

Ref:permission_required decorator doc

like image 41
Stefano Avatar answered Oct 16 '22 19:10

Stefano


I'm assuming this question requires two pieces

  • Users that are already logged in do not get redirected to the login page
  • Users that are not logged in do not get redirected

@Manoj Govindan's answer nor @Stefano's answer will not work. @Lidor's answer will work, but he has fully re-implemented the permission_required function.

Here is a simpler way:

@login_required
@permission_required('hi there', raise_exception=True)
def blah(request):
    pass

With this, if the user is not logged in, they will be redirected. If they are but they don't have permissions, they will be down an error.

like image 38
theicfire Avatar answered Oct 16 '22 20:10

theicfire


I had the same problem but learned about raise_exception parameter at the @permission_required decorator! this parameter is False by default, but once you pass it the True value, it will automatically redirect the without permission user to the 403.html page! (if there was any 403.html page in the root of your project, otherwise shows the server 403 forbidden page! read more in Django docs here

@permission_required('app_name.view_model', raise_exception=True)
    def some_model_view(request):
        ...
like image 30
mjavadtatari Avatar answered Oct 16 '22 19:10

mjavadtatari