基于类的视图:在哪里检查权限?

dab*_*aba 6 python django

我不太习惯使用基于类的视图,但我知道它们的好处,所以我强迫自己开始更频繁地使用它们。

有一个接收路径参数的视图:manage/:id管理特定实体。

class MyView(TemplateView):
  template_name = '...'

  def get_context_data(self, **kwargs):
    context = super(MyView, self).get_context_data(**kwargs)
    context['entity'] = get_object_or_404(Entity, pk=self.args[0])
    return context
Run Code Online (Sandbox Code Playgroud)

一个Entity包括被授权的用户的列表,以执行特殊行动。这个观点,MyView就是那些特别行动之一。

我尝试为视图制作一个装饰器,但它需要找到第Entity一个,所以我不确定如何解决这个问题。

现在,我有一个check_permission(request, entity)函数可以检查当前用户是否是这些授权用户之一。

我的问题是我应该在基于类的视图中在哪里调用这个函数,比如MyView这些视图中的哪一个被视为“特殊操作”?

我应该只调用它get_context_data()吗?

yed*_*tko 7

将其放入dispatch()。它可能看起来像这样:

class MyView(TemplateView):
   template_name = '...'

   def dispatch(self, request, *args, **kwargs):
       entity = get_object_or_404(Entity, pk=args[0])
       if not check_permission(request, entity):
           raise Http404
       return super(MyView, self).dispatch(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)


den*_*aar 6

您可以dispatch像 yedpodtrzitko 所说的那样检查权限。我认为把它放在一个可以放在你的观点上的 mixin 中也是一个好主意。

下面是一个例子:

from django.core.exceptions import PermissionDenied


class ViewPermissionsMixin(object):
    """Base class for all custom permission mixins to inherit from"""
    def has_permissions(self):
        return True 

    def dispatch(self, request, *args, **kwargs):
        if not self.has_permissions():
            raise PermissionDenied
        return super(ViewPermissionsMixin, self).dispatch(
            request, *args, **kwargs)

class MyCustomPermissionMixin(ViewPermissionsMixin):

    def has_permissions(self):
        # here you will have access to both
        # self.get_object() and self.request.user
        return self.request.user in self.get_object().special_list_of_people
Run Code Online (Sandbox Code Playgroud)

现在你可以抛出MyCustomPermissionMixin你的观点:

class MyView(MyCustomPermissionMixin, TemplateView):
    # ...
Run Code Online (Sandbox Code Playgroud)

在您的情况下,由于您使用的是 a TemplateView,因此您还应该创建一个get_object()返回要处理的对象的方法。模板视图默认没有这个方法。

最后,只想说,一旦您了解了有关如何使用它们的更多信息,您就会喜欢 Django 的基于类的视图。