36

I want to retrieve all permission for user as list of premission id's but:

user.get_all_permissions()

give me list of permission names. How to do it?

Paulo Bu
  • 29,294
  • 6
  • 74
  • 73
Nips
  • 13,162
  • 23
  • 65
  • 103

8 Answers8

50

to get all the permissions of a given user, also the permissions associated with a group this user is part of:

from django.contrib.auth.models import Permission

def get_user_permissions(user):
    if user.is_superuser:
        return Permission.objects.all()
    return user.user_permissions.all() | Permission.objects.filter(group__user=user)
Jonas Schäfer
  • 20,140
  • 5
  • 55
  • 69
DRC
  • 4,898
  • 2
  • 21
  • 35
  • I'm using this code but for some reason it's returning duplicate permissions. – Mike Stoddart May 13 '16 at 14:17
  • 3
    Here's an option for removing duplicates (presumably because they're group and user permissions): `list(set(chain(user.user_permissions.filter(content_type=ctype).values_list('codename', flat=True), Permission.objects.filter(group__user=user, content_type=ctype).values_list('codename', flat=True))))` Suspect chain is sometimes more efficient than |. The values_list calls and filter by content type are unnecessary but are further options depending on your needs. – Chris Aug 13 '16 at 18:39
  • 6
    I guess `return Permission.objects.filter(Q(group__in=user.groups.all())|Q(user=user)).distinct()` will dedup as well. – Paulo Scardine Oct 09 '19 at 15:04
  • It should be noted that although `user.has_perm("...")` will always return `True` for superusers, the user may not actually be associated with any `django.contrib.auth.models.Permission` records in the database. Also, revoking superuser status does not remove permission relationships from the user record. – Evan Byrne Feb 24 '20 at 15:53
27

The key is get the permission objects like this:

from django.contrib.auth.models import Permission
permissions = Permission.objects.filter(user=user)

and there you can access the id property like this:

permissions[0].id

If you want the list (id, permission_name) do the following:

perm_tuple = [(x.id, x.name) for x in Permission.objects.filter(user=user)]

Hope it helps!

dummy
  • 4,256
  • 3
  • 25
  • 36
Paulo Bu
  • 29,294
  • 6
  • 74
  • 73
12

If you are using Django 3.0+, user.get_user_permissions() gives the codename of all the permissions.

More information here: https://docs.djangoproject.com/en/3.0/ref/contrib/auth/#django.contrib.auth.models.User.get_user_permissions

atb00ker
  • 957
  • 13
  • 24
8

we can get user permission from user objects directly into a list like this

perm_list = user_obj.user_permissions.all().values_list('codename', flat=True)

Try this....

Shihabudheen K M
  • 1,347
  • 1
  • 13
  • 19
5

This is an routine to query for the Permission objects returned by user.get_all_permissions() in a single query.

from functools import reduce
from operator import or_
from django.db.models import Q
from django.contrib.auth.models import Permission

def get_user_permission_objects(user):
    user_permission_strings = user.get_all_permissions()
    if len(user_permission_strings) > 0:
        perm_comps = [perm_string.split('.', 1) for perm_string in user_permission_strings]
        q_query = reduce(
            or_,
            [Q(content_type__app_label=app_label) & Q(codename=codename) for app_label, codename in perm_comps]
        )
        return Permission.objects.filter(q_query)
    else:
        return Permission.objects.none()

Alternatively, querying Permission directly:

from django.db.models import Q
from django.contrib.auth.models import Permission

def get_user_permission_objects(user):
    if user.is_superuser:
        return Permission.objects.all()
    else:
        return Permission.objects.filter(Q(user=user) | Q(group__user=user)).distinct()


Moritz
  • 3,235
  • 26
  • 17
1
from django.contrib.auth.models import Permission
permissions = Permission.objects.filter(user=user)

permissions[0].id
ndrwnaguib
  • 5,623
  • 3
  • 28
  • 51
Amey Dhuri
  • 11
  • 2
1

Returns the set of permission strings the user_obj has, including both user permissions and group permissions. Returns an empty set if is_anonymous or is_active is False.

user_permissions_list = request.user.get_all_permissions()

Returns the set of permission strings the user_obj has from the permissions of the groups they belong. Returns an empty set if is_anonymous or is_active is False.

request.user.get_group_permissions()

Returns the set of permission strings the user_obj has from their own user permissions. Returns an empty set if is_anonymous or is_active is False.

request.user.get_user_permissions()

Unfortunately these built in method give me duplicate queries.

Or you can use your own filter from permission tables to get all permissions of current user

user_permissions_list = list(Permission.objects.filter(Q(user=request.user) | Q(group__user=request.user)).values_list('codename', flat=True))

Doc

Mahmudul Hassan
  • 357
  • 3
  • 10
0

Extending and explaining the answer from @Shihabudheen K M

we can get user permission from user objects directly a queryset like this

perm_queryset = user_obj.user_permissions.all().values_list('id')

The queryset obtained in this case is of the following format:

<QuerySet [(31,), (16,), (11,), (35,), (18,), (36,)]>

Flattened queryset of permissions of the user:

flattened_perm_queryset = user_obj.user_permissions.all().values_list('id', flat=True)

Output:

<QuerySet [31, 16, 11, 35, 18, 36]>

To get a list of the ids of these permissions on a user you can do:

perm_list = list(user_obj.user_permissions.all().values_list('id', flat=True))

Output:

[31, 16, 11, 35, 18, 36]

Hope this is helpful!