【问题标题】:How to set different permission_classes for GET and POST requests using the same URL?如何为使用相同 URL 的 GET 和 POST 请求设置不同的权限类?
【发布时间】:2019-08-28 04:58:36
【问题描述】:

我正在使用 DRF(Django Rest 框架)构建端点。

django==2.1.5
djangorestframework==3.9.1
django-rest-auth
djangorestframework-jwt

我有模型“项目”,我想为 GET 和 POST 请求设置不同的权限类。

这是我的做法:

@csrf_exempt
@api_view(['GET', 'POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([AllowAny])
def item_list(request):
    if request.method == 'GET':
        items = Item.objects.all()
        serializer = ItemSerializer(items, many=True)
        return JsonResponse(serializer.data, safe=False)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = ItemSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)

我想为所有方法使用一个端点,如下所示:

urlpatterns = [
    path('api/item/', views.item_list),
    path('api/item/<int:pk>/', views.item_details),
]

我想AllowAny用户为GET请求方法 并检查isAdminUser 是否为POST 请求方法

我可以像在 Flask 中那样做吗,即一种方法一个装饰器?

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    由于您使用的是基于功能的视图,因此无法覆盖任何方法。您现在可以做的是,创建一个新的 Permission 类并将您的逻辑包含在其中

    # permissions.py
    from rest_framework.permissions import IsAdminUser
    
    
    class MyCustomPermission(IsAdminUser):
        def has_permission(self, request, view):
            if request.method == 'GET':
                return True
            else:
                return super().has_permission(request, view)
    

    并在您的视图中使用它,

    # views.py
    @csrf_exempt
    @api_view(['GET', 'POST'])
    @authentication_classes([TokenAuthentication])
    @permission_classes([MyCustomPermission]) # chage is here 
    def item_list(request):
        if request.method == 'GET':
            items = Item.objects.all()
            serializer = ItemSerializer(items, many=True)
            return JsonResponse(serializer.data, safe=False)
    
        elif request.method == 'POST':
            data = JSONParser().parse(request)
            serializer = ItemSerializer(data=data)
            if serializer.is_valid():
                serializer.save()
                return JsonResponse(serializer.data, status=201)
            return JsonResponse(serializer.errors, status=400)
    


    如果您计划迁移到 基于类的视图,您可以通过覆盖 get_permissions() 方法来实现。

    你可以找到simple example here

    def get_permissions(self):
        """
        Instantiates and returns the list of permissions that this view requires.
        """
        if self.request.method == 'GET':
            permission_classes = [AllowAny]
        else:
            permission_classes = [IsAdminUser]
        return [permission() for permission in permission_classes]
    

    【讨论】:

      【解决方案2】:

      使用class based 视图,定义和使用custom permissions

      【讨论】:

        猜你喜欢
        • 2020-05-04
        • 1970-01-01
        • 2013-09-17
        • 2021-09-26
        • 1970-01-01
        • 1970-01-01
        • 2011-05-29
        • 1970-01-01
        • 2014-06-10
        相关资源
        最近更新 更多