使用Django的UserPassesTestMixin,灵活控制访问权限

想做的事情 zuò de

我希望只有自己才能编辑登录Django的用户信息。

即使尝试利用Django内置的Permission模型,对登录用户自身进行动态限制似乎相当困难。
因此,可以利用UserPassesTestMixin来实现。

UserPassesTestMixin是什么?

Django 1.9 中发布的用于基于类的视图的 Permission mixins 中包含的功能。
官方文档中也有详细解释。
使用 Django 的身份验证系统 | Django 文档 | Django

尝试使用UserPassesTestMixin

百闻不如一见,作为例子,我们尝试使用UserPassesTestMixin来定义一个仅允许gmail.com域名用户访问的视图。

用户通过测试的Mixin的扩展

首先,我们要定义一个自定义的Mixin,如下所示。

# mixins.py
from django.contrib.auth.mixins import UserPassesTestMixin

class OnlyGmailUserMixin(UserPassesTestMixin):
    raise_exception = True

    def test_func(self):
        return self.request.user.email.endswith('@gmail.com')

我将重写test_func方法,并在该方法内添加条件分支语句。
根据test_func的返回值,决定是否对其进行限制。

视图的定义

然后,我们定义一个继承自刚刚创建的自定义混入类的类视图。

# views.py
from django.contrib.auth.models import User
from django.views.generic import TemplateView

from .mixins import OnlyGmailUserMixin


class OnlyGmailUserView(OnlyGmailUserMixin, TemplateView):
    model = User
    template_name = "home.html"

就是这样了。非常简单!!!

定义一个只有自己可以编辑的视图

使用UserPassesTestMixin可以很容易地实现Django登录用户的个人信息只能由自己编辑。

# mixins.py
from django.contrib.auth.mixins import UserPassesTestMixin


class OnlyYouMixin(UserPassesTestMixin):
    raise_exception = True

    def test_func(self):
        user = self.request.user
        return user.pk == self.kwargs['pk']
# views.py
from django.contrib.auth.models import User
from django.views.generic import UpdateView

from .forms import UserForm # 別途フォームを定義しておく
from .mixins import OnlyYouMixin


class UserUpdateView(OnlyYouMixin, UpdateView):
    model = User
    template_name = "users/update.html"
    form_class = UserForm

    def get_success_url(self):
        return resolve_url('users:update', pk=self.kwargs['pk'])

总结

最近我第一次尝试使用UserPassesTestMixin,它是一个简单且富有应用性的Mixin,非常有趣。
但是需要注意的是,好像无法继承多个UserPassesTestMixin。

而且,关于最后的OnlyYouMixin,如果试图在除了User模型之外的模型中使用它,由于主键不同,无法顺利进行,因此似乎需要将处理更加抽象化一些。

bannerAds