1️⃣ 선요약
permission_classes = [A, B]
permission_classes = [A & B]
결과적으로 둘은 거의 같다. 그러나 실행 방식에 차이가 있고,
상황에 따라 다르지만, 논리곱(AND)연산만을 수행할 경우,
[A, B]의 방식이 일반적으로 조금 더 이점이 있다.
단, 두 조건을 중첩해서 OR과 비교할 경우(괄호를 통한 우선순위가 필요하다면),
&를 사용하는 것에 이점이 있다.
2️⃣ comma(,)를 사용했을 때
DRF의 .check_permissions(…) 메서드를 확인해보자.
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(…) 메서드를 호출한다.
3️⃣ & 연산자를 사용했을 때
반면에 & 연산자를 사용하면 .and 메서드를 사용하여 새 permission을 생성한다.
DRF의 and 연산자를 확인해보자.
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)
4️⃣ 차이점
따라서 이것은 본질적으로 첫 번째 피연산자에서 .has_permission(…)을 먼저 실행하고,
성공하면 두 번째 피연산자에서 실행하기 위한 meta-programming logic일 뿐이다.
5️⃣ 결론
그래서 두가지 방식은 동일한가?
정확히는 아니다.
& 연산자를 사용하면 message와 code가 사라지므로,
어떤 permission이 거부되었는지 정확히 추적할 수 없다.
기본 제공 permission은 message나 code가 없지만,
custom permission에 사용자가 직접 지정하고, view에서 사용했을 때,
해당 코드는 code와 message를 반환하지 않는다.
따라서 작은 디테일이지만 permission에 대해서 &연산만을 수행할 경우,
[A ,B]를 사용하는 것이 [A & B]에 비해 약간의 이점이 있다.
그러나 두 조건을 중첩해서 OR과 비교할 경우, &연산자의 경우 괄호를 사용하여 처리가 가능하나,
쉼표의 경우 구분자로 작동하기 때문에 괄호 안에 쓸 수 없다.
permission_classes = [(A & B) | C] # O
permission_classes = [(A , B) | C] # X
아래의 경우,
(A, B) or (C, D) 가 아니라
A, (B or C), D 로 작동한다.
permission_classes = [A, B | C, D] # A / B또는C / D
따라서 논리 연산 사용 시, 괄호를 통한 우선순위가 필요하다면, &를 쓰는 것이 유리하다고 할 수 있다.
'Python > Django' 카테고리의 다른 글
[Django] fixtures (0) | 2023.06.22 |
---|---|
[Django] bulk_create (0) | 2023.06.16 |
[DRF] Permissions (0) | 2023.06.10 |
[DRF] GenericAPIView와 Mixins (0) | 2023.06.07 |
[DRF] ModelSerializer와 CreateModelMixin 사용하기 (0) | 2023.06.06 |
댓글