对象级权限

时间:2017-05-31 17:21:11

标签: python django django-rest-framework django-permissions

我确信这是相当简单的,但我已经仔细检查了文档,我无法弄清楚如何做到这一点。

我已将User类扩展为与其他用户建立两个ManyToMany关系:trainersteammates

如果用户拥有一个对象(由模型上的user ForeignKey定义),那么该用户应该能够GETPOSTPUT,{ {1}}和PATCH。我已使用DELETE设置了这些端点。如果用户是所有者的培训师,则他们应具有相同的权限。如果用户是所有者的队友,则他们应该只能ModelViewSet

在这些对象的列表视图中,用户应该只能看到他们拥有的对象以及他们是所有者的培训师或队友的对象。如果他们尝试访问对象的详细视图,而对象不是所有者的朋友或队友,则应返回403.

我按如下方式扩展GET以尝试创建此行为 - 然后我将其添加到我想要此行为的BasePermission

ModelViewSet

由于REST Framework文档指定对于列表视图不是基于每个对象运行,因此我会覆盖class TrainerAndOwnerOrTeammate(permissions.BasePermission): def has_object_permission(self, request, view, obj): user = request.user owner = obj.user if user == owner: return True if user in owner.trainers.all(): return True if user in owner.teammates.all(): return request.method in permissions.SAFE_METHODS return False 以过滤请求用户。

问题是,如果我尝试访问我不应该访问的详细信息视图,我会收到404错误,而不是403错误。我理解为什么会发生这种情况,但有没有办法解决它?

2 个答案:

答案 0 :(得分:0)

我认为一种解决方案是删除get_queryset()并定义自定义过滤器。过滤器类允许您根据要访问的请求和视图过滤查询集。另一种方法是将视图集拆分为多个单独的视图。另一种方法是定义get_object。

答案 1 :(得分:0)

我最终覆盖了list的{​​{1}}方法并保留了权限类。权限类处理详细信息视图和操作,list方法处理列表视图。