同时使用LoginRequiredMixin和UserPassesTestMixin

时间:2017-11-03 11:53:28

标签: django python-3.x django-views mixins

我想要一个同时使用LoginRequiredMixin和UserPassesTestMixin的TemplateView类。像这样:

from django.views.generic import TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

class FinanceOverview(LoginRequiredMixin, UserPassesTestMixin, TemplateMixin):
    login_url = '/login'
    redirect_field_name = 'next'

    def test_func(self):
        return self.request.user.groups.filter(name="FinanceGrp").exists()

    def get(self, request, *args, **kwargs):
        DO SOMETHING IF USER IS AUTHENTICATED AND ALSO MEMBER OF GROUP FinanceGrp

基本上如上所述,我想要实现的目标如下:

  • 如果用户未经过身份验证,则将用户重定向到:

    https://website/login?next=financeoverview 
    
  • 但是,我无法弄清楚如何将经过身份验证但不属于 FinanceGrp 组的用户重定向到另一个页面。例如:

    https://website.com/access_denied?previous_page=financeoverview
    

在我的情况下,用户在组测试失败时总是被重定向到/ login页面。我怎样才能实现同时使用的两个mixin,但同时它们都在变量login_url之间发生冲突。不幸的是,UserPassesTestMixin正在使用相同的login_url,所以它给我带来了麻烦。

提前致谢

米洛斯

2 个答案:

答案 0 :(得分:1)

我认为你最好继承AccessMixin,然后自己执行这些检查。像这样:

from django.contrib.auth.mixins import AccessMixin
from django.http import HttpResponseRedirect 

class FinanceOverview(AccessMixin, TemplateMixin):

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            # This will redirect to the login view
            return self.handle_no_permission()
        if not self.request.user.groups.filter(name="FinanceGrp").exists():
            # Redirect the user to somewhere else - add your URL here
            return HttpResponseRedirect(...)

        # Checks pass, let http method handlers process the request
        return super().dispatch(request, *args, **kwargs)

答案 1 :(得分:0)

您应该覆盖get_login_url:

class FinanceOverview(LoginRequiredMixin, UserPassesTestMixin, TemplateMixin):
    login_url = '/login'
    redirect_field_name = 'next'

    def test_func(self):
        return self.request.user.groups.filter(name="FinanceGrp").exists()

    def get_login_url(self):
        if self.request.user.is_authenticated:
            return URL_FOR_AUTHENTICATED_USERS
        return super().get_login_url()

    def get(self, request, *args, **kwargs):
        DO SOMETHING IF USER IS AUTHENTICATED AND ALSO MEMBER OF GROUP FinanceGrp