Django UserPassesTestMixin 困惑/问题?

mas*_*j02 7 django django-views django-permissions django-class-based-views

我目前正在开发一个管理仪表板,其中仅包含标记为Business用户的公司管理员的特定视图。

该应用程序将有大约 10 次浏览,我有一些关于UserPassesTestMixin

基本上我所有的观点都会包括这一点,

def test_func(self):
    return self.request.user.user_type == 'Business'
Run Code Online (Sandbox Code Playgroud)

为了确保用户是Business用户,我以这种方式保护视图。

我自己无法解决的几个问题是:

现在,如果重复 10 次,是否有一种更干净的方法来做到这一点,而不是 def test_func在每个 CBV 中都采用这种方法?

出现的另一个问题是,如果用户没有通过测试,它会重定向到登录页面,我也不喜欢这个页面。这些视图都返回 json。如果用户没有通过测试,我想将他们发送到类似的地方,

JsonResponse({'message': 'Only company administrators have access to this view'})
Run Code Online (Sandbox Code Playgroud)

仅当用户未通过测试时,我如何才能更改该重定向?请记住,这些视图也继承自LoginRequiredMixin其中,如果用户未登录,我想保持登录页面的原始重定向不变。

非常感谢对此的任何帮助。Django 的这一面对我来说相当新鲜!

Wil*_*sem 18

现在重复了 10 次,是否有一种更干净的方法来做到这一点,而不是test_func在每个 CBV 中都有 def ?

是的,您可以简单地创建一个实现检查的 mixin:

from django.contrib.auth.mixins import UserPassesTestMixin

class BusinessUserMixin(LoginRequiredMixin, UserPassesTestMixin):
    
    def test_func(self):
        return self.request.user.user_type == 'Business'

    def handle_no_permission(self):
        return JsonResponse(
            {'message': 'Only company administrators have access to this view'}
        )
Run Code Online (Sandbox Code Playgroud)

然后你在你的视图中使用这个mixin,例如:

class MyView1(BusinessUserMixin, ListView):
    # …
    pass

class MyView2(BusinessUserMixin, DetailView):
    # …
    pass

class MyView3(BusinessUserMixin, CreateView):
    # …
    pass
Run Code Online (Sandbox Code Playgroud)

如果用户没有通过测试,它会重定向到登录页面,我也不喜欢这个页面。这些视图都返回 json。如果用户没有通过测试,我想将他们发送到类似的地方。

handle_no_permission您也可以重写该方法,当测试失败时,视图将返回该方法的结果作为结果。

  • 杰出的!这正是我一直在寻找的。再次非常非常感谢! (2认同)