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

标签 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_classes。

这是我的做法:

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

最佳答案

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

并在您的 View 中将其用作,

# views.py
@csrf_exempt
@api_view(['GET', 'POST'])
@authentication_classes([TokenAuthentication])
<b>@permission_classes([MyCustomPermission]) # chage is here </b>
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)
<小时/> <小时/>

如果您计划迁移到基于类的 View ,您可以通过覆盖 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]

关于python - 如何使用相同的URL为GET和POST请求设置不同的permission_classes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55549786/

相关文章:

python - Numpy power 不允许负值

python - 使用 xlwings 将数据帧打印到特定的列/行位置,例如 (1,2)

python - 如果满足某些条件,Django 中间件为 'do nothing'

python - 获取 django 对象的一对多设置属性的名称

python - 属性错误: 'property' object has no attribute 'copy' - while trying to get object list in Django Rest

django - 带有 DRF 的带有 cookie 的 Nuxt 身份验证

django-rest-framework - django-rest-swagger 如何记录 API

python - 在 python 中添加和创建列表 block

python - 从 Django 连接到 MySQL

python - Django 测试模型根据它们的位置加载?