如何获取用户权限?

36

我想要检索用户的所有权限,并将其作为权限ID列表返回,但是:

user.get_all_permissions()

请给我权限名称列表。如何操作?


你为什么需要那个? - karthikr
我需要这个来在我的表单中设置ModelMultipleChoiceField中的正确复选框。 - Nips
你是否将权限暴露给应用程序了?这不是一个好主意。 - karthikr
在我的应用程序中,我有一个自定义表单用于添加用户,并显示一些权限(针对我的应用程序)作为复选框。请参见:http://stackoverflow.com/questions/16565277/how-to-checked-permissions-in-edit-user-form - Nips
8个回答

50

获取特定用户的全部权限,以及该用户所属组中关联的权限:

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)

我正在使用这段代码,但出现了重复权限的问题。 - Mike Stoddart
3
下面是去除重复项的选项(可能是因为它们是组和用户权限):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))))。怀疑链式调用相比使用 | 符号有时更有效率。values_list 和按 content type 进行过滤是不必要的,但可以根据您的需求考虑其他选项。 - Chris
6
我猜return Permission.objects.filter(Q(group__in=user.groups.all())|Q(user=user)).distinct()也会去重。 - Paulo Scardine
需要注意的是,虽然对于超级用户 user.has_perm("...") 总是返回 True,但用户实际上可能没有与数据库中的任何 django.contrib.auth.models.Permission 记录相关联。此外,撤销超级用户状态不会从用户记录中删除权限关系。 - Evan Byrne

27

关键是获取权限对象的方式如下:

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

你可以通过以下方式访问 id 属性:

permissions[0].id

如果您想要列表 (id,permission_name),请执行以下操作:

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

希望它有所帮助!


4
如果用户所在的群组具有该权限,会怎样? - Amogh Talpallikar
@AmoghTalpallikar 我已经得到了一个答案来解决你指出的这个问题。 - DRC
1
就像@AmoghTalpallikar所说的那样,这并没有涵盖当一个组拥有用户没有的权限,但是用户是该组的成员的情况。 - theEpsilon
对于使用Django 3.0+的人:https://dev59.com/BmQn5IYBdhLWcg3wxZri#62290977 - atb00ker

12

8
我们可以直接从用户对象中获取用户权限,并将其放入列表中,如下所示。
perm_list = user_obj.user_permissions.all().values_list('codename', flat=True)

尝试这个...


5
这是一种查询user.get_all_permissions()返回的Permission对象的常规方法,可以通过单个查询实现。
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()

另外,可以直接查询权限:

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
返回用户对象 user_obj 拥有的权限字符串集合,包括用户权限和组权限。如果 is_anonymous 或 is_active 为 False,则返回一个空集合。 user_permissions_list = request.user.get_all_permissions() 返回用户对象 user_obj 所属组的权限字符串集合。如果 is_anonymous 或 is_active 为 False,则返回一个空集合。

request.user.get_group_permissions()

返回用户对象从其自身用户权限中拥有的权限字符串集合。如果 is_anonymous 或 is_active 为 False,则返回空集合。

request.user.get_user_permissions()

不幸的是,这些内置方法会给我重复的查询。
或者,您可以使用来自权限表的自己的过滤器来获取当前用户的所有权限。 user_permissions_list = list(Permission.objects.filter(Q(user=request.user) | Q(group__user=request.user)).values_list('codename', flat=True)) 文档

0

扩展并解释@Shihabudheen K M的答案

我们可以直接从用户对象的查询集中获取用户权限,如下所示

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

在这种情况下获得的查询集的格式如下:

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

用户权限的扁平化查询集:

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

输出:

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

要获取用户权限的 ID 列表,您可以执行以下操作:

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

输出:

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

希望这对你有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接