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?

4
  • why do you need that?
    – karthikr
    Commented May 15, 2013 at 19:23
  • I need this to set proper checkboxes in ModelMultipleChoiceField in my form
    – Nips
    Commented May 15, 2013 at 19:26
  • are you exposing permissions to the application? it is not a good idea.
    – karthikr
    Commented May 15, 2013 at 19:27
  • In my app I have custom form for adding users and I shows some permissions (for my app) as checkboxes. See: stackoverflow.com/questions/16565277/…
    – Nips
    Commented May 15, 2013 at 19:31

8 Answers 8

52

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)
4
  • I'm using this code but for some reason it's returning duplicate permissions. Commented May 13, 2016 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
    Commented Aug 13, 2016 at 18:39
  • 7
    I guess return Permission.objects.filter(Q(group__in=user.groups.all())|Q(user=user)).distinct() will dedup as well. Commented Oct 9, 2019 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
    Commented Feb 24, 2020 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!

4
  • 4
    What if the user is in a group which has that permission ? Commented Dec 5, 2014 at 12:39
  • @AmoghTalpallikar I've hadden an aswer to address this issue you pointed out.
    – DRC
    Commented Dec 23, 2014 at 16:32
  • 1
    Like what @AmoghTalpallikar said, this doesn't cover the case when a group has a permission the user does not but the user is a member of that group.
    – theEpsilon
    Commented May 4, 2020 at 18:49
  • For people using Django 3.0+ : stackoverflow.com/a/62290977/6410464
    – atb00ker
    Commented Jun 9, 2020 at 20:05
14

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

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....

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()


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

permissions[0].id
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

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!

Not the answer you're looking for? Browse other questions tagged or ask your own question.