Django同一接口GET/PUT/DELETE设置差异化权限无需拆分URL方案
最优实现方案:自定义差异化权限类
你当前的写法是给整个视图绑定了全局的IsAuthenticated权限,所以所有请求方法都要鉴权。要实现不同方法不同权限,最优雅的方式是自定义权限类针对请求方法做判断,不需要拆分视图函数,也不需要额外新增URL配置。
实现步骤
- 自定义适配需求的权限类:
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权限类,不需要额外自定义。
- 替换原有视图的权限配置,原有业务逻辑不需要做任何修改:
@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
相关产品推荐
相关产品推荐

