如何使用相同的URL为GET和POST请求设置不同的Permission_class ??

时间:2019-04-06 13:57:39

标签: python django django-rest-framework

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

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

我有模型“ Item”,我想为GET和POST请求设置不同的Permission_class。

这是我的方法:

@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中那样做吗,即一种方法的装饰器吗?

2 个答案:

答案 0 :(得分:2)

由于您使用的是基于功能的视图,因此无法覆盖任何方法。您现在可以做的是,创建一个新的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]

答案 1 :(得分:1)

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