Django 是否未考虑\u对象\u权限

Django 是否未考虑\u对象\u权限,django,django-rest-framework,Django,Django Rest Framework,我试图使用Django Rest Framework强制执行一个权限,在这个权限中,特定用户不能发布包含非其用户id的对象 例如,我不希望用户使用其他id发布反馈 我的模型是这样的: class Feedback(Model): user = ForeignKey(User) ... 我试图在我的视图上设置一个权限,将feedback.user.id与request.user.id进行比较,在对象上发布正确的工作ok并返回false,但它仍在发布我的对象。。。为什么? 视图 c

我试图使用Django Rest Framework强制执行一个权限,在这个权限中,特定用户不能发布包含非其用户id的对象

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

我的模型是这样的:

class Feedback(Model):
    user = ForeignKey(User)
    ...
我试图在我的视图上设置一个权限,将feedback.user.id与request.user.id进行比较,在对象上发布正确的工作ok并返回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。 在这里,我想知道这是否真的是实现这种行为的方法,如果不是,那会是什么。。。?
谢谢。

您的问题是,只有当您试图访问某个对象时,才会调用has\u object\u权限。所以在创作中,它从未被实际使用过

我建议你做验证检查。例如:

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
如果您有一些其他的超级序列化程序类,那么只需更改它

现在我想如果user字段必须始终是posting用户,那么您应该将该字段设置为只读,并在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)

    ....

您的问题是,只有在您尝试访问某个对象时,才会调用has_object_权限。所以在创作中,它从未被实际使用过

我建议你做验证检查。例如:

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
如果您有一些其他的超级序列化程序类,那么只需更改它

现在我想如果user字段必须始终是posting用户,那么您应该将该字段设置为只读,并在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)

    ....

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

class IsSelf(permissions.BasePermission):

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

正如所选答案中所述

has_object_权限仅在您试图访问某个对象时调用


因此,您必须将您的条件置于您的许可之下。

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

class IsSelf(permissions.BasePermission):

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

正如所选答案中所述

has_object_权限仅在您试图访问某个对象时调用


因此,您必须将您的条件置于has_permission下。

但就是这样,这个函数实际上被调用了!如果它没有被调用,我会得出相同的结论,但它被调用,它确实返回false,但仍然没有被考虑,而这,我不明白。。。不过,关于pre_save的部分正是我一直在寻找的建议,所以非常感谢!创建对象后,它将显示在DRF中。因此,当has_object_permissions()试图显示您创建的对象时,可能会调用它。哦,好吧,实际上可能是这样的。。。我想我必须遵循另一个方向。但就是这样,这个函数实际上被调用了!如果它没有被调用,我会得出相同的结论,但它被调用,它确实返回false,但仍然没有被考虑,而这,我不明白。。。不过,关于pre_save的部分正是我一直在寻找的建议,所以非常感谢!创建对象后,它将显示在DRF中。因此,当has_object_permissions()试图显示您创建的对象时,可能会调用它。哦,好吧,实际上可能是这样的。。。我想我必须遵循另一个方向。has permission不允许我们使用
obj
var作为inputhas permission不允许我们使用
obj
var作为输入