2017-07-29 36 views
0

我想要简单的方法来检查是否有人是postproposal等的所有者或管理员,他正在尝试编辑\ delete。Django(drf)动态权限从BasePermission

所以,每次我用IsAuthenticated许可,并在ModelViewSet的方法,我得到的实例和时间是否instance.author或有时是谁要求它(在某些对象是request.user == instance.authorrequest.user == instance.owner)的用户。

问题

的主要问题是:我怎么可以创建许可类,它可以检查这种动态用户拥有对实例属性的名字吗?

一矿的解决方案(不是最好的,我认为)

我创建功能需要用户属性实例名称返回权限类:

def is_owner_or_admin_permission_factory(owner_prop_name): 
    class IsOwnerOrAdmin(BasePermission): 
     def has_permission(self, request, view, *args, **kwargs): 
      instance = view.get_object() 
      try: 
       owner = getattr(instance, owner_prop_name) 
      except AttributeError: 
       return False 
      return (
       request.user and request.user.id and (owner == request.user or request.user.is_staff) 
      ) 

    return IsOwnerOrAdmin 

回答

0

我也一直在受挫几天之后的确切问题,并且在处理具有用户属性的不同查找名称的多个模型时,我设法找到了适合的解决方法(至少对我来说当然是这样)。

解决方法是这样的,在ModelViewSet定义一个单独的属性user_lookup_kwarg在视图中,它可以用于检查适当的权限。

例如,

class YourViewSet(viewsets.ModelViewSet): 
    queryset = YourModel.objects.all() 
    serializer_class = YourSerializer 
    user_lookup_kwarg = 'user' #or 'account/created_by' whatever. 

现在,你permission_class会有点像这样,

class CustomPermission(BasePermission): 

    def has_object_permission(self, request, view, obj): 
     try: 
      return request.user.is_superuser or getattr(obj, view.user_lookup_kwarg) == request.user 
     except: 
      pass 
     return request.user.is_superuser 

你只只需要重写has_object_permission()方法来检查实例级别的权限。

+0

这对我来说完美无缺!再次感谢! – Dionid

+0

有一点:当你检查'request.user.is_superuser'和它的返回'True'时,它将从方法返回,如果它是'False'并且第二个参数产生异常,你可以返回'False',因为'request .user.is_superuser'必须已经是'False'。 – Dionid

+0

另外,我认为最好检查用户是否被授权,因为(在大多数情况下)'AnonymousUser'不能是对象的所有者,所以他需要被授权。 – Dionid