has_object_permission没有考虑在内

时间:2014-08-26 14:18:24

标签: django django-rest-framework

我正在尝试使用Django Rest Framework强制执行权限,其中特定用户无法发布包含不是他的用户ID的对象。

例如,我不希望用户使用其他ID发布反馈。

我的模型类似于:

class Feedback(Model):
    user = ForeignKey(User)
    ...

我尝试在我的视图上设置权限,将feedback.user.id与request.user.id进行比较,在对象的帖子上正确工作正常并返回false,但它仍然发布我的对象。 ..为什么?

视图

class FeedbackViewSet(ModelViewSet):
    model = Feedback
    permission_classes = (IsSelf,)
    serializer_class = FeedbackSerializer

    def get_queryset(self):
        ....

权限

class IsSelf(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        #return eval(obj.user.id) == request.user.id
        return False

我评论了这条线,以显示问题所在。 再次正确调用该函数并返回False,但是没有引发PermissionDenied。 虽然在它,我想知道这是否实际上是实现这种行为的方式,如果不是,那会是什么......? 感谢。

2 个答案:

答案 0 :(得分:3)

您的问题是,只有在您尝试访问某个对象时才会调用has_object_permission。所以在创作时它从未真正使用过。

我建议您检查验证。示例:

class FeedbackSerializer(HyperlinkedModelSerializer):

    def validate(self, attrs):
        user = self.context['request'].user
        if attrs['user'].id !=  user.id:
            raise ValidationError('Some exception message')
        return attrs

如果您有其他超级序列化程序类,则只需更改它。

现在我想到如果用户字段必须始终是发布用户,那么您应该只将该字段设置为只读并在viewset类中的pre_save()上设置它。

class FeedbackViewSet(ModelViewSet):

    def pre_save(self, obj, *args, **kwargs):
        if self.action == 'create':
            obj.user = self.request.user

在序列化程序中,将用户字段设置为只读

class FeedbackSerializer(HyperlinkedModelSerializer):
    user = serializers.HyperlinkedRelatedField(view_name='user-detail', read_only=True)

    ....

答案 1 :(得分:0)

我不知道这是否仍然开放...... 但是,为了工作,您应该将该行从“has_object_permission”移动到“has_permission”,如下所示:

class IsSelf(permissions.BasePermission):

def has_permission(self, request, view, obj):
    if request.method == 'POST':
        #your condition

为我工作。

如所选答案中所述

  只有在您尝试访问某个对象时才会调用

has_object_permission

所以你必须将你的条件置于 has_permission 之下。