Django Rest框架创建时权限检查

6
为什么 Django Rest Framework 在创建对象时不检查对象权限呢?对我来说这没有任何意义,一个用户应该只能创建他可以看到、更新或删除的对象。目前,我会像下面这样子类化一个视图集:
class CheckCreatePermissionsViewSet(ModelViewSet):
    def perform_create(self, serializer):
    '''
    Called by create before calling serializer.save()
    '''
    obj = serializer.save()
    try:
        self.check_object_permissions(obj)
    except:
        obj.delete()
        raise

为什么这不是默认实现?这给我带来了很多麻烦,而且我想不到有任何理由会这样实现。

3个回答

1
我认为在创建对象之前调用业务逻辑验证比先创建对象再判断用户是否可以看到并删除它更自然和明确。
class CheckCreatePermissionsViewSet(ModelViewSet):
    def perform_create(self, serializer):
        try:
            business_rules_are_ok(serializer.data, user):
        except BusinessException:
            raise ValidationError(<content from BusinessException)
        serializer.save()

如果你认为需要的话,应该使用serializer.validated_data而不是serializer.data - luc

0
如果您的意图不是在用户没有特定权限时创建对象,那么您可以在Viewset中使用permission_classes,这样Viewset甚至不会允许用户创建对象。
为什么需要根据权限创建然后再删除呢?最好先检查权限,以便如果权限失败,则对象根本不会被创建。
例如,您只想让管理员创建对象,您可以将permission_classes=[permissions.IsAdminUser]添加到viewset中,这样控制权甚至不会进入perform_create。如果普通用户尝试创建对象,Viewset将发送403。希望这正是您想要的。

0
在我的方法中,我使用了perform_create来完成您提出的工作。但是,我没有创建和删除它,而是使用事务来处理它,代码如下:
class CheckCreatePermissionsViewSet(ModelViewSet):
    def check_object_permissions(self, request, obj):
        super(type(self), self).check_object_permissions(request, obj)
        #Additional logic....
        if not request.user.is_staff:
            raise PermissionDenied()


    def perform_create(self, serializer):
        with transaction.atomic():
            super(type(self), self).perform_create(serializer)
            obj = serializer.instance
            self.check_object_permissions(self.request, obj)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接