【问题标题】:How to set permissions per handler function with APIView?如何使用 APIView 为每个处理函数设置权限?
【发布时间】:2020-07-09 11:16:32
【问题描述】:

我正在使用 Django 和 Django-Rest-Framework 为一个与学校相关的小型项目编写 API。我正在尝试找出权限。

我正在为我的视图使用 APIView,并希望为每个处理程序方法设置不同的权限,而无需编写更多视图。

这是我对博客模块的看法之一:

(此视图用于/posts/

from .serializers import *
from django.db.models import Case, When
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.decorators import permission_classes
from rest_framework import status, permissions


# Create your views here.
class PostList(APIView):
    """
    API Endpoint to List Posts
    METHODS: GET, POST
    """

    @permission_classes([permissions.AllowAny,])
    def get(self, request, format=None):
        posts = Post.objects.all()
        serializer = PostSerializer(posts, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    @permission_classes([permissions.IsAuthenticated])
    def post(self, request, format=None):
        serializer = PostCreationSerializer(data=request.data)
        if serializer.is_valid():
            obj = serializer.save()
            data = serializer.data
            data["id"] = obj.id
            return Response(data, status=status.HTTP_201_CREATED)
        return Response(status=status.HTTP_400_BAD_REQUEST)

当前的默认值为permissions.IsAuthenticated,尽管更改它不一定有帮助,因为我仍然需要单独更改一些权限。

所以我应该能够在未通过/posts/ 验证的情况下发出 GET 请求并获得所有帖子的列表,而我应该从对/posts/ 的 POST 请求中获得 401。但是,即使是 GET 请求也会返回 401 状态码。

这样做的正确方法是什么……如果有的话。

编辑:虽然我提供了自己问题的答案,但我仍然想知道是否有更正确的方法来解决这个问题。

【问题讨论】:

    标签: python django django-rest-framework permissions


    【解决方案1】:

    我想出了一个解决方案,但我不确定这是不是最好的方法。

    首先,我们创建一个 APIView 的子类:

    from rest_framework.views import APIView
    
    
    class CustomAPIView(APIView):
        def get_permissions(self):
            # Instances and returns the dict of permissions that the view requires.
            return {key: [permission() for permission in permissions] for key, permissions in self.permission_classes.items()}
    
        def check_permissions(self, request):
            # Gets the request method and the permissions dict, and checks the permissions defined in the key matching
            # the method.
            method = request.method.lower()
            for permission in self.get_permissions()[method]:
                if not permission.has_permission(request, self):
                    self.permission_denied(
                        request, message=getattr(permission, 'message', None)
                    )
    

    然后我们使用 CustomAPIView 写出视图,并使用 permission_classes 的字典,其中键是方法。

    例子:

    # Create your views here.
    class PostList(CustomAPIView):
        """
        API Endpoint to List Posts
        METHODS: GET, POST
        """
        permission_classes = {"get": [permissions.AllowAny], "post": [permissions.IsAuthenticated]}
    
        def get(self, request, format=None):
            posts = Post.objects.all()
            serializer = PostSerializer(posts, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
    
        def post(self, request, format=None):
            serializer = PostCreationSerializer(data=request.data)
            if serializer.is_valid():
                obj = serializer.save()
                data = serializer.data
                data["id"] = obj.id
                return Response(data, status=status.HTTP_201_CREATED)
            return Response(status=status.HTTP_400_BAD_REQUEST)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-18
      • 2016-12-23
      • 2019-04-04
      • 2021-08-18
      • 2022-01-21
      • 2019-07-25
      • 1970-01-01
      • 2019-04-05
      相关资源
      最近更新 更多