如何使用 CBV 将权限拒绝重定向到另一个页面?



我有一个具有权限的模型,在我看来使用 CBV(通用。创建视图(或(通用。DetailView(,如果登录的用户具有权限,则他可以访问视图,如果没有访问权限,则显示"禁止 403"页面。

但是,如果用户没有该视图的权限,我希望引发异常 PermissionDenied,并重定向到此错误的特定页面。

我的观点:

class AddJob(LoginRequiredMixin, PermissionRequiredMixin, generic.CreateView)
permission required = 'can_create_job'
model = Job
fields = ['name', 'description', 'salary']
success_url = reversy_lazy('job_list)
context_object_name = 'object_name'

谁能帮我? 谢谢

首先,您不能同时进行重定向引发 404 异常

也就是说,如果用户没有权限,您可以重定向到某个页面引发异常。情况 1:引发异常 要引发异常
,您应该在视图类中添加raise_exception = True为,


class AddJob(LoginRequiredMixin, PermissionRequiredMixin, generic.CreateView):
permission_required = 'can_create_job'
model = Job
fields = ['name', 'description', 'salary']
success_url = reversy_lazy('job_list')
context_object_name = 'object_name'
raise_exception = True # Change is here

情况2:重定向到特定页面
在您的视图中设置login_url

class AddJob(LoginRequiredMixin, PermissionRequiredMixin, generic.CreateView):
permission_required = 'can_create_job'
model = Job
fields = ['name', 'description', 'salary']
success_url = reversy_lazy('job_list')
context_object_name = 'object_name'
login_url = '/path/to/specific/page'



如果同时设置login_urlraise_exception会发生什么?

AccessMixin类有一个方法handle_no_permission(),正在调用该方法来处理这种情况。

源代码

def handle_no_permission(self):
if self.raise_exception:
raise PermissionDenied(self.get_permission_denied_message())
return redirect_to_login(self.request.get_full_path(), self.get_login_url(), self.get_redirect_field_name())

在这里你可以看到,如果你设置raise_exception = True,django 不会考虑login_url

你可以做的是添加raise_exception = True来查看类,这将引发PermissionDenied,即返回403(禁止(http状态的响应。请参阅 https://docs.djangoproject.com/en/dev/topics/auth/default/#django.contrib.auth.mixins.AccessMixin.raise_exception

另外,如果你想显示自己的 403 页面,你可以创建403.html模板,django 会在返回 403 时使用它。见 https://docs.djangoproject.com/en/dev/ref/views/#the-403-http-forbidden-view

这里解决了很多问题,但只是想我会添加一些选项:

如果你想以某种标准化的方式完全控制不同的视图,你可以通过子类化 Django 来创建自己的混合:

class MyAccessMixin(AccessMixin):
""" A custom AccessMixing to handle access denied from PermissionRequired """
permission_denied_message = "Oupsies! You do not have access!"
def handle_no_permission(self):
messages.info(self.request ,self.permission_denied_message)
# or specific redirects based on context 
return redirect(reverse_lazy(self.my_perm_denied_url_string))

假设您重定向到的 URL 显示来自框架的消息,它将向用户显示。

当然,您可以将mixin添加到您的视图中,例如:

class AddJob(LoginRequiredMixin, PermissionRequiredMixin, MyAccessMixin, generic.CreateView):
# code

最新更新