How to get a list of all users with a specific permission group in Django

64,411

Solution 1

If you want to get list of users by permission, look at this variant:

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

perm = Permission.objects.get(codename='blogger')  
users = User.objects.filter(Q(groups__permissions=perm) | Q(user_permissions=perm)).distinct()

Solution 2

This would be the easiest

from django.contrib.auth import models

group = models.Group.objects.get(name='blogger')
users = group.user_set.all()

Solution 3

I think for group permissions, permissions are stored against groups, and then users have groups linked to them. So you can just resolve the user - groups relation.

e.g.

518$ python manage.py shell

(InteractiveConsole)
>>> from django.contrib.auth.models import User, Group
>>> User.objects.filter(groups__name='monkeys')
[<User: cms>, <User: dewey>]

Solution 4

Based on @Glader's answer, this function wraps it up in a single query, and has been modified to algo get the superusers (as by definition, they have all perms):

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

def users_with_perm(perm_name):
    return User.objects.filter(
        Q(is_superuser=True) |
        Q(user_permissions__codename=perm_name) |
        Q(groups__permissions__codename=perm_name)).distinct()

# Example:
queryset = users_with_perm('blogger')

Solution 5

Do not forget that specifying permission codename is not enough because different apps may reuse the same codename. One needs to get permission object to query Users correctly:

def get_permission_object(permission_str):
    app_label, codename = permission_str.split('.')
    return Permission.objects.filter(content_type__app_label=app_label, codename=codename).first()

def get_users_with_permission(permission_str, include_su=True):
    permission_obj = get_permission_object(permission_str)
    q = Q(groups__permissions=permission_obj) | Q(user_permissions=permission_obj)
    if include_su:
        q |= Q(is_superuser=True)
    return User.objects.filter(q).distinct()

Code with imports: https://github.com/Dmitri-Sintsov/django-jinja-knockout/blob/master/django_jinja_knockout/models.py

Share:
64,411
David Stevens
Author by

David Stevens

Updated on July 05, 2022

Comments

  • David Stevens
    David Stevens almost 2 years

    I want to get a list of all Django auth user with a specific permission group, something like this:

    user_dict = {
        'queryset': User.objects.filter(permisson='blogger')
    }
    

    I cannot find out how to do this. How are the permissions groups saved in the user model?

  • David Stevens
    David Stevens over 15 years
    Thanks, that fixed it, i knew should be simple. The only problem is if the group name is changed, maybe i should filter it on ID or something instead... But thanks!
  • João dos Reis
    João dos Reis almost 10 years
    I have a basic Model that has this requirement - filter a list of users on a certain object-level permission (django-guardian). What's the best way to do this - on the Model, on a ModelForm or a separate Form?
  • marcelm
    marcelm over 7 years
    I think this query needs a | Q(is_superuser=True) ;)
  • FMCorz
    FMCorz over 4 years
    Best answer. Although note that content_type__model=model should also be included.
  • shad0w_wa1k3r
    shad0w_wa1k3r almost 4 years
    Slightly better & lazier query - User.objects.filter(Q(groups__permissions__codename="blogger‌​") | Q(user_permissions__codename="blogger") | Q(is_superuser=True))
  • DJ Ramones
    DJ Ramones over 3 years
    @marcelm good catch, though there are use cases for which this is not desirable, such as when the list of users fetched is for an action that is opt-in, i.e. shouldn't affect superusers unless they explicitly want to.