如何将视图限制仅对超级用户可见?

33

view.py

@login_required
@permission_required('is_superuser')
def score_reset(request):
   pass

url.py

url(r'^score-reset/$', score_reset, name='score-reset'),    

我有以下代码,但令我惊讶的是,尽管我使用的不是超级用户登录,但我仍然调用了该函数。我本来期望会收到权限被拒绝的错误信息。

我错过了什么?

6个回答

63

顺便说一下,我没有将此标记为重复项,因为我链接的任何答案都没有提到user_passes_test是一个现有的Django装饰器,以及is_superuser不是权限。 - Timmy O'Mahony
2
问题要求仅限超级用户访问。示例代码应为@user_passes_test(lambda u: u.is_superuser)。 - mhost
1
使用user_passes_test [上面的代码片段]可以完成工作。但是您可能需要考虑,即使非超级用户已经登录,这也将重定向到登录页面。您可能需要编写自己的装饰器来完成工作。 - ALLSYED

7
以上的答案似乎是针对 Django 的早期版本。它们比后来的版本要复杂一些。 对于 Django 1.11,这里有一个类似但更简单的策略。 views.py
from django.contrib.auth.decorators import login_required

@login_required
def some_view(request):
if request.user.is_superuser:
    //allow access only to superuser
    return render(request, 'app/template1.html', args)
else:
    //allow access only to user
    return render(request, 'app/template2.html', args)

5

利用 Django 的 UserPassesTestMixin

创建一个自定义的 mixin,名为 SuperuserRequiredMixin

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

class SuperuserRequiredMixin(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.is_superuser

使用方法

class SomeSuperUserOnlyView(SuperuserRequiredMixin, ListView):
    form_class = ExamForm
    template_name = 'exam/newexam.html'

2

@user_passes_test并不是一个优雅的解决方案,如果你想在许多视图上执行此检查。你可以轻松编写自己的装饰器,例如@staff_member_require。

这里你可以看到可能的解决方案之一。


1
您可以使用用户通过测试装饰器来限制访问方式。以下是基于用户电子邮件的限制示例:
from django.contrib.auth.decorators import user_passes_test

def email_check(user):
    x = False
    if user.email == 'anyemailhere':
        x = True
    return x

# Create your views here.
@user_passes_test(email_check)
def dash_index(request):
    ...

更多内容请参考https://docs.djangoproject.com/en/2.1/topics/auth/default/#the-permission-required-decorator


0

SuperuserRequiredMixin

另一个基于权限的mixin。这是专门用于要求用户为超级用户。对于只有特权用户才能访问的工具非常方便。

首先安装:pip install django-braces

views.py

from braces.views import LoginRequiredMixin, SuperuserRequiredMixin


class SomeSuperuserView(LoginRequiredMixin, SuperuserRequiredMixin, TemplateView):
    template_name = "path/to/template.html"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接