You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django同一接口GET/PUT/DELETE设置差异化权限无需拆分URL方案

最优实现方案:自定义差异化权限类

你当前的写法是给整个视图绑定了全局的IsAuthenticated权限,所以所有请求方法都要鉴权。要实现不同方法不同权限,最优雅的方式是自定义权限类针对请求方法做判断,不需要拆分视图函数,也不需要额外新增URL配置。

实现步骤

  1. 自定义适配需求的权限类:
from rest_framework.permissions import BasePermission

class IsAuthenticatedForWrite(BasePermission):
    def has_permission(self, request, view):
        # GET请求直接放行,其他请求需要身份验证
        if request.method == 'GET':
            return True
        return request.user and request.user.is_authenticated

如果你需要兼容OPTIONS、HEAD这类默认安全请求也公开,可以把判断条件改成if request.method in ('GET', 'HEAD', 'OPTIONS')。如果刚好符合这个通用逻辑,也可以直接用DRF自带的IsAuthenticatedOrReadOnly权限类,不需要额外自定义。

  1. 替换原有视图的权限配置,原有业务逻辑不需要做任何修改:
@api_view(['GET', 'PUT', 'DELETE'])
@permission_classes([IsAuthenticatedForWrite]) # 换成自定义权限或者自带的IsAuthenticatedOrReadOnly
def getOrUpdateOrDeleteCar(request, pk):

    if request.method == 'GET':
        vehicle = Car.objects.get(id=pk)
        serializer = CarSerializer(vehicle, many=False)

        return Response(serializer.data)
    elif request.method == 'PUT':
        data = request.data
        car = Car.objects.get(id=pk)

        car.image=data['image']
        car.make=data['make']
        car.prototype=data['prototype']
        car.year=data['year']
        car.serviceInterval=data['serviceInterval']
        car.seats=data['seats']
        car.color=data['color']
        car.vin=data['vin']
        car.currentMileage=data['currentMileage']

        car.save()

        serializer = CarSerializer(car, many=False)
        return Response(serializer.data)
    elif request.method == 'DELETE':
        car = Car.objects.get(id=pk)
        car.delete()
        return Response('Car Deleted!')

这个方案的优势是权限规则可复用,视图逻辑内聚,不需要调整URL配置。

内容的提问来源于stack exchange,提问作者Sog t

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:54:05