2013-03-03 35 views
2

假设我的应用就像一个论坛,但每个帖子都有一组人可能会看到它。Django:基于对象的属性使用基于类的视图进行身份验证

SecretPost(Model): 
    can_see = myapp.main.models.GroupOfUsers() 

我想写这限制了用户对这些职位访问的观点,我宁愿使用的装饰,因为这是如何我一直在处理访问控制其他任何地方。

SecretPostView(DetailView): 
    """Can only be seen by members of its group""" 

    @method_decorator(part_of_its_group) 
    def dispatch(self, request, *args, **kwargs): 
     return super(SecretPostView, self).dispatch(request, *args, **kwargs) 

但是,当dispatch()被调用时,我不知道任何关于该对象。在对象已被检索后,是否有一种很好的/惯用的方法来限制用户访问?

回答

2

你可以在方法装饰器里面访问self,所以你做的有权访问当前调用的对象self.get_object()。不管怎样,如果你只在通用视图上使用这种行为,你可能最好创建一个实现dispatch方法(或可能是get_object方法)的混合,并在那里进行检查(使用稍加想象的,因为你的IDK的群体是如何定义的,也许你正在使用django.contrib.auth组):

class GroupRestrictionMixin(object): 
    group_field = 'group' 

    def dispatch(request, *args, **kwargs): 
     self.request = request 
     self.args = args 
     self.kwargs = kwargs 

     obj_group = getattr(self.get_object(), self.group_field) 
     user_groups = request.user.groups 

     if obj_group not in user_groups: 
      raise PermissionDenied 

     return super(GroupRestrictionMixin, self).dispatch(request, *args, **kwargs) 

然后您可以创建使用的mixin需要的是行为的任何观点:

class SecretPostView(GroupRestrictionMixin, DetailView): 
    pass 

Idk如果它是你所说的“惯用”,但这是想到保持简单和可重用的简单方法。

编辑:请求,args和kwargs必须在这里设置,所以get_object方法有权访问它们。它有一点丑陋(你必须重复一些基于dispatch方法的代码),但仍然有效:F

+0

嗯......当我在'dispatch'方法中调用'get_object'时,出现一个错误,对象没有'kwargs'属性。 – 2013-03-03 04:04:54

+0

前段时间我做了一个编辑,解释了为什么。我没有意识到这一点,但是我自己测试了一下,发现调度方法是将'request','args'和'kwargs'属性赋予通用视图的方法。 – asermax 2013-03-03 04:34:49

相关问题