假设我们有以下基于类的视图 (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
或者你必须使用基于函数的视图来实现这种行为?
您可以制作仅检查特定方法的权限的东西:
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]
# …