笨拙的重复 - 我自己的django权限检查

时间:2017-09-16 05:11:05

标签: django

我有一个Problem对象的基于类的视图。我只希望Problem的作者能够查看Problem cbv。其他登录用户应重定向到禁止页面。

我通过检查get_template_name()方法中的所有权来实现此目的。但是,如果我想将上下文传递给禁止的模板,我还需要检查get_context_data()中的所有权并制作适当的上下文。

这很有效,但它看起来像是太多的半重复代码,而且非常非Pythonic / Djangonic。

有人建议更好的方法吗?这是我创建的许多ClassBasedViews的问题。我有“问题”对象和“Board”对象,我想确保logged-in user == the authorProblem对象的Board。几乎看起来我可以拥有某种Mixin或其他东西。

无论如何,这是我的方法的一个例子:

class ProblemStudyView(UpdateView):
    model = Problem
    fields = "__all__"

    def get_template_names(self):
        problem = self.get_object()
        if problem.author != self.request.user:
            # User should not see this entry
            context = {'original_author': problem.author, 'request_user': self.request.user}
            template_name = "board/forbidden.html"
            return template_name
        else:
            # This user is OK
            template_name = "board/study.html"
            return template_name

    def get_context_data(self, **kwargs):
        context = super(ProblemStudyView, self).get_context_data(**kwargs)

        problem = self.get_object()

        # Do the permission check a second time to setup correct context
        if problem.author != self.request.user:
            context = {'original_author': problem.author, 'request_user': self.request.user}
            return context
        else:
            # User is ok; proceed as normal           
            return context

1 个答案:

答案 0 :(得分:0)

您可以使用PermissionRequiredMixin和自定义权限。

我会做这样的事情:

from django.contrib.auth.mixins import PermissionRequiredMixin


class ProblemStudyView(PermissionRequiredMixin, UpdateView):

    model = Problem
    fields = "__all__"
    permission_denied_message = 'YOURMESSAGEHERE'
    raise_exception = True
    template_name = 'board/study.html'

    def dispatch(self, request, *args, **kwargs):
        self.request = request  # needed for has_permission
        self.kwargs = kwargs  # needed for get_object
        return super().dispatch(request, *args, **kwargs)

    def has_permission(self):
        problem = self.get_object()
        return problem.author == self.request.user

由于引发了PermissionDeniedException,您可以使用(或更改)标准的Django http禁止视图: https://docs.djangoproject.com/en/1.11/ref/views/#the-403-http-forbidden-view