CBV有两个定义相同方法的Mixin-如何让每个Mixin执行自己的代码



编辑:在这个问题上发现了相同的场景:同时使用LoginRequiredMixin和UserPassesTestMixin

我的观点有2个混合:

class FooView(LoginRequiredMixin, EmailVerifiedMixin, View):
        ...

EmailVerifiedMixin是我写的Mixin

class EmailVerifiedMixin(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.email_verified
    def handle_no_permission(self):
        return redirect(reverse("confirm_account"))

问题是,当Anonymous用户转到该视图时,他们会从LoginRequiredMixin的handle_no_permission((重定向到confirm_account,而不是我的login_url。查看此视图的MRO:

>>> pprint(FooView.__mro__)
(<class 'foo_app.views.FooView'>,
 <class 'django.contrib.auth.mixins.LoginRequiredMixin'>,
 <class 'foo_app.views.EmailVerifiedMixin'>,
 <class 'django.contrib.auth.mixins.UserPassesTestMixin'>,
 <class 'django.contrib.auth.mixins.AccessMixin'>,
 <class 'django.views.generic.base.View'>,
 <class 'object'>)
>>> FooView.handle_no_permission
<function EmailVerifiedMixin.handle_no_permission at 0x7fbc46d8f1f0>

我认为EmailVerifiedMixin只是覆盖了LoginRequiredMixinhandle_no_permission()?如何同时使用这两种Mixin?

为了清楚起见:所需的行为是,如果用户没有登录,则重定向到login_url。如果他们已经登录,让他们通过EmailVerifiedMixin

我不喜欢它,但它很管用。我不会在这里接受我自己的答案,所以如果你知道如何回答问题,请仍然回答。

class EmailVerifiedMixin(LoginRequiredMixin, UserPassesTestMixin):
    def test_func(self):
        return self.request.user.email_verified
    def handle_no_permission(self):
        try:
            login_redirect = super().handle_no_permission()
            return login_redirect
        except PermissionDenied:
            return redirect(reverse("confirm_account"))

现在只需在FooView 上使用EmailVerifixedMixin

最新更新