您可以在基于类的视图中为每个函数设置权限类吗?

问题描述 投票:0回答:1

假设我们有以下基于类的视图 (CBV) 实现 DRF

APIView
:

class ExampleListAPIView(APIView):
    permission_classes = [IsAuthenticatedOrReadOnly]

    def get(self, request):
        '''
        List all examples
        '''
        examples = Example.objects.all()
        serializer = ExampleListSerializer(examples, many=True)

        return Response(serializer.data, status.HTTP_200_OK)

    def post(self, request):
        '''
        Create new example
        '''
        serializer = ExampleListSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

使用

permission_classes
在CBV中设置认证策略,该策略应用于类的所有方法。是否可以在 CBV 中设置每个功能的权限,例如

class ExampleListAPIView(APIView):
    def get(self, request): # Apply [AllowAny]
        # logic

    def post(self, request): # Apply [IsAuthenticated]
        # logic

或者你必须使用基于函数的视图来实现这种行为?

python django django-rest-framework permissions
1个回答
0
投票

您可以制作仅检查特定方法的权限的东西:

class ForMethod(BasePermission):
    def __init__(self, permission, *methods):
        self.permission = permission
        self.methods = set(map(str.casefold, methods))

    def __call__(self):
        return self

    def has_permission(self, request, view):
        if request.method.casefold() in self.methods:
            self.permission().has_permission(request, view)
        return True

    def has_object_permission(self, request, view, obj):
        if request.method.casefold() in self.methods:
            self.permission().has_object_permission(request, view, obj)
        return True

并与:

合作
class ExampleListAPIView(APIView):
    permission_classes = [
        ForMethod(AllowAny, 'get'),
        ForMethod(IsAuthenticated, 'post'),
    ]

    def get(self, request):  # Apply [AllowAny]
        # logic
        pass

    def post(self, request):  # Apply [IsAuthenticated]
        # logic
        pass

您甚至可以将其用作权限的代数

PostAuthenticated = ForMethod(AllowAny, 'get') & ForMethod(
    IsAuthenticated, 'post'
)


class ExampleListAPIView(APIView):
    permission_classes = [PostAuthenticated]
    # …
© www.soinside.com 2019 - 2024. All rights reserved.