#18763: Shortcut to get users by permission
------------------------------+--------------------
     Reporter:  shelldweller  |      Owner:  nobody
         Type:  New feature   |     Status:  new
    Component:  contrib.auth  |    Version:  master
     Severity:  Normal        |   Keywords:
 Triage Stage:  Unreviewed    |  Has patch:  0
Easy pickings:  0             |      UI/UX:  0
------------------------------+--------------------
 In my apps I often need to get the list of users who have a specific
 permission. But it seems there is no shortcut to do this in Django itself
 (unless I'm missing something obvious). And getting users by permission is
 slightly more complicated than may appear at first sight because user
 permission can be set at user level or at group level, and also we need to
 pay special attention to superusers.

 So I usually end up doing something like this:

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

 def get_users_by_permission_q(permission_name, include_superusers=True):
     """ Returns the Q object suitable for querying users by permission. If
 include_superusers
     is true (default) all superusers will be also included. Otherwise
     only users with explicitely set permissions will be included. """
     (appname, codename) = permission_name.split(".")

     query = \
         Q(user_permissions__codename=codename,
 user_permissions__content_type__app_label=appname) | \
         Q(groups__permissions__codename=codename,
 groups__permissions__content_type__app_label=appname)

     if include_superusers:
         query |= Q(is_superuser=True)

     # The above query may return multiple instances of User objects if
 user
     # has overlapping permissions. Hence we are using a nested query by
 unique
     # user ids.
     return {'pk__in': User.objects.filter(query).distinct().values('pk')}

 def get_users_by_permission(permission_name, include_superusers=True):
     """ Returns the queryset of User objects with the given permission.
 Permission name
     is in the form appname.permission similar to the format
     required by django.contrib.auth.decorators.permission_required
     """
     return User.objects.filter( get_users_by_permission_q(permission_name,
 include_superusers) )
 }}}

 And them in my models.py:

 {{{
 class MyModel:
     my_fk_field = models.ForeignKey(User,
 limit_choices_to=dict(is_active=True, \
         *get_users_by_permission_q("myapp.change_my_model", False)))
 }}}

 Or in my views:
 {{{
 users = get_users_by_permission("myapp.change_my_model")
 }}}

 It would be nice to have something like this in
 django/contrib/auth/utils.py

 If this proposal gets accepted I can contribute a patch.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/18763>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to