2017-05-31 319 views
0

我相信这是相当直接的,但我已经搜遍了文档,我无法弄清楚如何做到这一点。对象级权限

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

如果用户拥有的对象(由user ForeignKey的上模型中定义的),则该用户应该能够GETPOSTPUTPATCH,和DELETE。我已经用ModelViewSet设置了这些端点。如果用户是所有者的培训者,他们应该拥有相同的权限。如果用户是业主的队友,他们应该只能够GET

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

我扩展了BasePermission以尝试创建此行为 - 然后添加它到我想要这种行为的ModelViewSet

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 

由于REST框架文档指定这不是基于每个对象的基础上进行列表视图运行,我推翻get_queryset由请求用户进行过滤。

现在的问题是我得到一个404错误,而不是403,如果我尝试访问我不应该访问的详细视图。我了解为什么发生这种情况,但有没有办法解决它?

回答

0

我最终覆盖了ModelViewSetlist方法并保留权限类。权限类处理了详细视图和操作,列表方法处理了列表视图。

0

我认为一个解决方案是放下get_queryset()并定义一个自定义过滤器。筛选器类使您可以根据访问的请求和视图筛选查询集。另一种方法是将您的视图分成多个单独的视图。另一种方法是定义get_object。