django permission_classes = [A,B]和permission_classes = [A & B]之间有区别吗?

polkgigr  于 2023-06-25  发布在  Go
关注(0)|答案(2)|浏览(148)

这两个有什么区别

permission_classes = [A, B] 
permission_classes = [A & B]

??
我理解第一个是按顺序处理权限的,第二个是一次处理。
结果有差别吗?
我也想知道哪种方法是首选的,为什么。

tktrz96b

tktrz96b1#

简而言之:列表或元组中的两个或更多元素是可取的。

从语义上讲,两者几乎是一样的。实际上,Django会检查**.check_permissions(…)**方法[GitHub]中的权限:

def check_permissions(self, request):
    """
    Check if the request should be permitted.
    Raises an appropriate exception if the request is not permitted.
    """
    for permission in self.get_permissions():
        if not permission.has_permission(request, self):
            self.permission_denied(
                request,
                message=getattr(permission, 'message', None),
                code=getattr(permission, 'code', None),
            )

因此,它枚举列表中的项,当其中一个权限失败时,它调用.permission_denied(…)方法,其中包含失败的权限的消息和代码。
另一方面,如果你使用&操作符,它将构造一个新的权限,使用**.__and__(…)**方法[GitHub]:

class OperationHolderMixin:
    def __and__(self, other):
        return OperandHolder(AND, self, other)

# …

class OperandHolder(OperationHolderMixin):
    def __init__(self, operator_class, op1_class, op2_class):
        self.operator_class = operator_class
        self.op1_class = op1_class
        self.op2_class = op2_class

    def __call__(self, *args, **kwargs):
        op1 = self.op1_class(*args, **kwargs)
        op2 = self.op2_class(*args, **kwargs)
        return self.operator_class(op1, op2)

    # …

class AND:
    def __init__(self, op1, op2):
        self.op1 = op1
        self.op2 = op2

    def has_permission(self, request, view):
        return self.op1.has_permission(request, view) and self.op2.has_permission(
            request, view
        )

    def has_object_permission(self, request, view, obj):
        return self.op1.has_object_permission(
            request, view, obj
        ) and self.op2.has_object_permission(request, view, obj)

因此,这本质上只是一些元编程逻辑,首先在第一个操作数上运行.has_permission(…),如果成功,则在第二个操作数上运行。
所以这两者似乎是等价的?不完全是,通过使用&.message.code就消失了,所以我们无法追溯到底是哪个权限检查被拒绝了。虽然大多数(所有)内置权限没有消息或代码,但如果您自己为自定义权限检查指定一个权限,并且该权限检查在运算符中使用,则该表达式的结果将丢失代码和消息。
因此,虽然这是可能的,但使用[perm1, perm2]比使用[perm1 & perm2]有一个小优势

yhuiod9q

yhuiod9q2#

permission_classes = [A, B] # User has both A and B
permission_classes = [A & B] # User has both A and B
permission_classes = [A | B] # User either A or B

选择最适合您的特定情况或编码风格的一个。

相关问题