Django 中基于 class 的视图的身份验证

Authentication for class based views in Django

class AdminView(generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

class AdminUpdateView(UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

我在 django 中创建了两个视图,我希望只有在 admin/staff 登录时才能访问它们。我该怎么做?

您可以使用 UserPassesTestMixin:

from django.contrib.auth.mixins import UserPassesTestMixin

class AdminView(UserPassesTestMixin, generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

    def test_func(self):
        return self.request.user.is_staff or self.request.user.is_superuser

您可以使用 UserPassesTestMixin [Django-doc] and LoginRequiredMixin [Django-doc] 混入,并指定用户应该是 is_superuser 作为条件。既然你需要两次,我们可以先做一个复合mixin:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin

class AdminStaffRequiredMixin(LoginRequiredMixin, UserPassesTestMixin):

    def test_func(self):
        return <b>self.request.user.is_superuser or self.request.user.is_staff</b>

接下来,您可以将 mixin 添加到基于 class 的视图中:

class AdminView(<b>AdminStaffRequiredMixin,</b> generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

class AdminUpdateView(<b>AdminStaffRequiredMixin,</b> UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

使用装饰器,@login_required 你可以告诉这个视图只有在用户 os 登录时才能访问,你也可以传递参数给它或者创建一个你自己的来验证是否请求中的登录用户可以看到或看不到您的视图

需要登录

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
class AdminView(generic.ListView):
    ...

@login_required(login_url='/accounts/login/')
class AdminUpdateView(UpdateView):
    ...

https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-login-required-decorator

经许可

from django.contrib.auth.decorators import permission_required

@permission_required('user.is_staff')
def my_view(request):
    ...

https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-permission-required-decorator

如果你想使用LoginRequiredMixin,你仍然可以。而且要简单得多。只需在所有 类 中扩展 LoginRequiredMixin,使它们像这样。

class AdminView(LoginRequiredMixin, generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

class AdminUpdateView(LoginRequiredMixin, UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

这确保用户在允许任何操作之前已经登录。然后,通过将以下代码添加到每个 类;

来检查用户是否是管理员
def dispatch(self, request, *args, **kwargs):
    if not self.request.user.is_staff:
        raise PermissionDenied
    return super().dispatch(request, *args, **kwargs)

您的代码现在应该如下所示:

class AdminView(LoginRequiredMixin, generic.ListView):
    model = get_user_model()
    fields = ['first_name', 'username', 'is_active']
    template_name = 'users/admin.html'

    def dispatch(self, request, *args, **kwargs):
        if not self.request.user.is_staff:
            raise PermissionDenied
        return super().dispatch(request, *args, **kwargs)

class AdminUpdateView(LoginRequiredMixin, UpdateView):
    model = get_user_model()
    fields = ['is_active']
    template_name = 'users/user_update.html'
    success_url = reverse_lazy('users:admin')

    def dispatch(self, request, *args, **kwargs):
        if not self.request.user.is_staff:
            raise PermissionDenied
        return super().dispatch(request, *args, **kwargs)

你可以使用IsAdminUser rest框架的权限

from rest_framework import permissions

class AdminView(generic.ListView):
    permission_classes = (permissions.IsAdminUser, )
    ...