我有一个Problem
对象的基于类的视图。我只希望Problem
的作者能够查看Problem
cbv。其他登录用户应重定向到禁止页面。
我通过检查get_template_name()
方法中的所有权来实现此目的。但是,如果我想将上下文传递给禁止的模板,我还需要检查get_context_data()
中的所有权并制作适当的上下文。
这很有效,但它看起来像是太多的半重复代码,而且非常非Pythonic / Djangonic。
有人建议更好的方法吗?这是我创建的许多ClassBasedViews的问题。我有“问题”对象和“Board”对象,我想确保logged-in user == the author
或Problem
对象的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
答案 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