How to refer or access the custom made permissions in has_perm() and in required_permissions?

Hi there,

I want to know that how do I refer the custom made permissions in the has_perm() method of User Model and required_permissions attribute of PermissionRequiredMixin Class?

Let’s say I create the following custom permission:

content_type = ContentType.objects.get_for_model(User)

Permission.objects.create(
                codename='custom_permission',
                name='Custom Permission',
                content_type=content_type,
            )

and suppose my django app where I created this custom permission is named as:

mycustomapp

How will I refer/access this custom permission in has_perm() method and required_permissions attribute?

I tried following for has_perm()

from django.contrib.auth.models import Permission

user = User.objects.all()[0]
user.user_permissions.add(Permission.objects.get(name="Custom Permission"))
user.save()

user.has_perm("mycustomapp.user.custom_permission")

But it resulted in False, instead of True, even though running user.user_permissions.all() show the newly added permission

and I tried this for required_permissions attribute:

class CustomView(PermissionRequiredMixin, View):
    required_permission = ["mycustomapp.user.custom_permission"]

But it does not work and when I go to this View on front-end I get Forbidden 403 error, even though the logged in user has this required permission.

Can anyone tell me how do I refer the custom made permission in has_perm() and in required_permissions. Please tell me while considering all the details exactly as I gave above in example.

It should just be mycustomapp.custom_permission. See Custom permissions and the various examples starting at Using the Django authentication system | Django documentation | Django showing permissions being used.

1 Like

@KenWhitesell thanks, it’s solved after I tried what you said. But now I want to add permissions as a bulk from Permission Class. For example, I want to do something like this:

user.user_permissions.add(Permission.objects.filter(name__icontains="workspace"))

I tried the above example in python shell, but it gives me the following error:

Traceback (most recent call last):
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\db\models\fields\__init__.py", line 1988, in get_prep_value 
    return int(value)
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'QuerySet'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1048, in add 
    self._add_items(
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1263, in _add_items
    target_ids = self._get_target_ids(target_field_name, objs)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1197, in _get_target_ids
    target_ids.add(target_field.get_prep_value(obj))
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\db\models\fields\related.py", line 1132, in get_prep_value  
    return self.target_field.get_prep_value(value)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\db\models\fields\__init__.py", line 1990, in get_prep_value 
    raise e.__class__(
TypeError: Field 'id' expected a number but got <QuerySet [<Permission: accounts | workspace | Can add workspace>, <Permission: accounts | 
workspace | Can Add User To Workspace DataMeister>, <Permission: accounts | workspace | Can Add User To Workspace PricingMeister>, <Permission: accounts | workspace | Can Add User To Workspace TestingWorkspace1>, <Permission: accounts | workspace | Can Remove User From Workspace DataMeister>, <Permission: accounts | workspace | Can Remove User From Workspace PricingMeister>, <Permission: accounts | workspace | Can Remove User From Workspace TestingWorkspace1>, <Permission: accounts | workspace | Can View User From Workspace DataMeister>, <Permission: accounts | workspace | Can View User From Workspace PricingMeister>, <Permission: accounts | workspace | Can View User From Workspace TestingWorkspace1>, <Permission: accounts | workspace | Can change workspace>, <Permission: accounts | workspace | Can delete workspace>, <Permission: accounts | workspace | Can view workspace>]>.

How can I accomplish it? How can I add the filtered bulk of permissions from Permission class to any user?

The add method expects each object instance to be added to be a separate positional parameter. You can take advantage of the *args pattern to pass the list as a list of positional parameters.

You should be able to do something like:
user.user_permissions.add(*Permission.objects.filter(name__icontains="workspace"))

or, if that fails due to some error:
user.user_permissions.add(*list(Permission.objects.filter(name__icontains="workspace")))

(Note: I’m winging this, I haven’t had a chance to actually try it.)

1 Like

@KenWhitesell it worked perfectly

But, when I tried to print all user permissions with following command:

user.user_permissions.objects.all()

it gave me following result in the form of QuerySet:

<QuerySet [<Permission: accounts | workspace | Can add workspace>, <Permission: accounts | workspace | Can Add User To Workspace DataMeister>, <Permission: accounts | workspace | Can Add User To Workspace PricingMeister>, <Permission: accounts | workspace | Can Add User To Workspace TestingWorkspace1>, <Permission: accounts | workspace | Can Remove User From Workspace DataMeister>, <Permission: accounts | workspace | Can Remove User From Workspace PricingMeister>, <Permission: accounts | workspace | Can Remove User From Workspace TestingWorkspace1>, 
<Permission: accounts | workspace | Can View User From Workspace DataMeister>, <Permission: accounts | workspace | Can View User From Workspace PricingMeister>, <Permission: accounts | workspace | Can View User From Workspace TestingWorkspace1>, <Permission: accounts | workspace | Can change workspace>, <Permission: accounts | workspace | Can delete workspace>, <Permission: accounts | workspace | Can view workspace>]>

I wanted to know that is the result in QuerySet fine? Should not it be a list?

The all method always returns a queryset. It is no different here than it is in any other query.

Side note - Review the Permissions and authorization docs. The ManyToManyField already is an implicit reference to a manager. (Also see Related objects reference | Django documentation | Django) You do not need to reference the objects manager in addition to it. The proper reference is user.user_permissions.all(), not user.user_permissions.objects.all().

1 Like