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