我正在尝试使用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。 虽然在它,我想知道这是否实际上是实现这种行为的方式,如果不是,那会是什么......? 感谢。
答案 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 之下。