假设我的应用就像一个论坛,但每个帖子都有一群人可以看到它。
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()
时,我对该对象一无所知。在检索到对象后,是否存在限制用户访问的良好/惯用方法?
答案 0 :(得分:2)
您可以访问方法装饰器中的self
,这样做就可以访问当前调用self.get_object()
的对象。
无论如何,如果你只是在通用视图上使用这种行为,你可能最好创建一个实现dispatch
方法的mixin(或者可能是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
如果它是你所谓的“惯用语”,请点击,但这是让它变得简单和可重复使用的更容易的方式。
编辑:必须在此处设置请求,args和kwargs,以便get_object
方法可以访问它们。它有点丑陋(你必须重复一些基于dispatch
方法的代码),但仍然有效:F