我的文件如下:
BusinessActionsPermission
class BusinessActionsPermission(BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
business_obj = view.get_business_obj()
if request.method in ['GET']:
return request.user.has_perm('act_on_business', business_obj)
if request.method in ['PUT', 'PATCH', 'DELETE']:
return request.user.has_perm('act_on_business', business_obj)
return False
EmployeeViewSet
class EmployeeViewSet(viewsets.ModelViewSet):
serializer_class = EmployeeSerializer
permission_classes = (permissions.IsAuthenticated, BusinessActionsPermission)
def get_business_obj(self, **kwargs):
return Business.objects.filter(pk=self.kwargs['business_id'])
def get_queryset(self, **kwargs):
return Employee.objects.filter(business__id=self.kwargs['business_id'])
def create(self, request, *args, **kwargs):
business = Business.objects.get(pk=self.kwargs['business_id'])
employee = Employee(business=business)
serializer = EmployeePOSTSerializer(employee, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors)
在调用BusinessActionsPermission
至POST
来创建新的Employee
方法时,EmployeeViewSet
不起作用。没有act_on_busienss
的用户可以post
并创建员工。
Django Rest Framework文档here说:
出于性能方面的考虑,当返回对象列表时,通用视图不会自动将对象级别权限应用于查询集中的每个实例。
这很好。 BusinessActionsPermission
正在为detailed retrievals with pk
工作。但是不能在不是post
的{{1}}上工作。
请帮助。
注意:上面的list
可以很好地用于详细视图,并且不检查列表视图,这在文档中已经提到了。但是BusinessActionsPermission
呢?
答案 0 :(得分:0)
由于还没有对象,因此DRF永远不会调用has_object_permission
方法,因此您应该在POST
方法中确定对has_permission
方法的许可。
还请注意,通用视图将仅检查对象级别 检索单个模型实例的视图的权限。
基本上,如果调用了get_object
方法,将检查对象级别权限。 drf source code
答案 1 :(得分:0)
如果您在rest_framework中查看ModelViewSet和泛型的实现,则可以了解何时检查了对象的权限。
使用has_object_permission
类的get_object
方法检索对象时,将调用BusinessActionsPermission GenericAPIView
方法。
因此,据此了解,在您的情况下,创建新对象时不会调用此方法。
您需要做的是将逻辑从has_object_permission
移到has_permission
。
您可以使用has_object_permission
来检查已创建的特定对象的权限(例如所有权)。