TransWikia.com

When to use UserPassesTestMixin vs PermissionRequiredMixin

Stack Overflow Asked by David Jay Brady on December 27, 2021

It seems to me that these mixins can accomplish similar goals in different ways. I can let someone access a view by checking if the user has a permission with PermissionRequiredMixin, or I can use UserPassesTest and write a test_func that checks if a user is in a particular group, or even check the permission there.

I’m new to Django and am having trouble knowing when to use one versus the other. In isolation I understand what they do, but not well enough to understand where they are appropriate.

A couple scenarios I’ve come across I’m not certain which is best

  • Which should I use to limit access to certain views?
  • In an app where users can create objects, limiting updating/deletion of these objects to the creator

2 Answers

  • PermissionRequiredMixin: Verify that the current user has all specified permissions.

  • UserPassesTestMixin: Deny a request with a permission error if the test_func() method returns False.

As the name suggests PermissionRequiredMixin only checks the permissions that are defined either in permission_required attribute or get_permission_required() method.

But, the UserPassesTestMixin is much generic version, which helps you to check any number of arbitrary conditions. For example, you can check the logged-in user's email domain, or any custom attributes, or values etc.


Example-1

In this example, both are equal.
from django.contrib.auth import mixins
from django.views import generic


class TestPermissionView(mixins.PermissionRequiredMixin, generic.CreateView):
    permission_required = [
        'foo.add_bar',
        'foo.change_bar'
    ]


class TestUserTestView(mixins.UserPassesTestMixin, generic.CreateView):
    def test_func(self):
        req_perms = [
            'foo.add_bar',
            'foo.change_bar'
        ]
        
        return self.request.user.has_perms(req_perms)

In this example, both classes behave in the same way

Example-2

class TestUserTestView(mixins.UserPassesTestMixin, generic.CreateView):
    def test_func(self):
        # this  checks the email domain of the user
        allowed_domains = ['foo.com', 'bar.co.in']
        return self.request.user.email.split('@')[1] in allowed_domains

In this example, we are checking the user's email domain. As you can see, this example can not be re-written using PermissionRequiredMixin class.

Answered by JPG on December 27, 2021

Test and Permission classes are not alternatives to each other.

You should use PermissionMixin for limiting users' actions. You may write your permission logic directly on view but that classes are the generic ways and recommended if you'll use it multiple times on the project.

And you may want to test it with a Test class. For make sure your code part works as wanted.

Answered by ishak O. on December 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP