permission_required装饰师不适合我

时间:2009-08-13 00:31:09

标签: django django-admin

我无法弄清楚为什么必需的装饰器不能正常工作。我想只允许工作人员访问视图。我试过了

@permission_required('request.user.is_staff',login_url="../admin")
def series_info(request):
  ...

以及

@permission_required('user.is_staff',login_url="../admin")
def series_info(request):
  ...

作为超级用户,我可以访问该视图,但我作为工作人员创建的任何用户都无法访问它并被重定向到登录URL页面。我测试了login_required装饰器,工作正常。

5 个答案:

答案 0 :(得分:22)

permission_required()必须传递权限名称,而不是字符串中的Python表达式。试试这个:

from contrib.auth.decorators import user_passes_test
def staff_required(login_url=None):
    return user_passes_test(lambda u: u.is_staff, login_url=login_url)

@staff_required(login_url="../admin")
def series_info(request)
...

  

感谢。这确实有效。你有吗?   如何使用的例子   permission_required?来自   文件   docs.djangoproject.com/en/1.0/...和   djangobook.com/en/2.0/chapter14我   我以为我应该工作。

重新阅读您发布的链接; permission_required()将测试用户是否已被授予特定权限。它不测试用户对象的属性。

来自http://www.djangobook.com/en/2.0/chapter14/

def vote(request):
    if request.user.is_authenticated() and request.user.has_perm('polls.can_vote')):
        # vote here
    else:
        return HttpResponse("You can't vote in this poll.")

   #
   #
 # # #
  ###
   #

def user_can_vote(user):
    return user.is_authenticated() and user.has_perm("polls.can_vote")

@user_passes_test(user_can_vote, login_url="/login/")
def vote(request):
    # vote here

   #
   #
 # # #
  ###
   #

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote', login_url="/login/")
def vote(request):
    # vote here

答案 1 :(得分:3)

我就是这样做的:

from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def series_info(request):
    ...

文档说明了staff_member_required:

  

用于视图的装饰器,用于检查用户是否已登录并且是工作人员,必要时显示登录页面。

答案 2 :(得分:1)

以下是我不理解的行为示例。我使用permission_required检查'is_staff'来创建用户,请求并修饰测试函数。如果用户是超级用户,则授予测试功能访问权限。如果用户只有is_staff = True,则不授予访问权限。

from django.http import HttpRequest
from django.contrib.auth.models import User
from django.contrib.auth.decorators import permission_required

@permission_required('is_staff')
def test(dummy='dummy'):
    print 'In test'

mb_user = User.objects.create_user('mitch', 'mb@home.com', 'mbpassword')
mb_user.is_staff = True

req = HttpRequest()
req.user = mb_user

test(req) # access to test denied - redirected

req.user.is_staff = False

test(req) # same as when is_staff is True

req.user.is_superuser = True
test(req) # access to test allowed

答案 3 :(得分:1)

顺便说一下,如果您使用基于类的视图,则应将装饰器包装在method_decorator装饰器中(如图所示):

class MyView(DetailView):
    ...
    @method_decorator(permission_required('polls.can_vote', login_url=reverse_lazy('my_login')))
    def dispatch(self, request, *args, **kwargs):
        .... blah ....

class MyModel(models.Model):
    ...
    def has_perm(self perm, obj=None):
        if perm == 'polls.canvote':
            return self.can_vote()

答案 4 :(得分:0)

这适用于我的“项目”表/模型:

@permission_required('myApp.add_project')
def create(request):
    # python code etc...

显然将add_project更改为add_ [无论你的模型/表是什么]。编辑它将是:

@permission_required( 'myApp.edit_project')

并删除:

@permission_required( 'myApp.delete_project')

但我发现关键是要确保你的auth表设置正确。这就是我遇到问题的原因。这是我编写的MySQL SQL查询,用于在使用组时检查权限。这应该适用于大多数dB:

select usr.id as 'user id',usr.username,grp.id as 'group id',grp.name as 'group name',grpu.id as 'auth_user_groups',grpp.id as 'auth_group_permissions',perm.name,perm.codename
from auth_user usr
left join auth_user_groups grpu on usr.id = grpu.user_id
left join auth_group grp on grpu.group_id = grp.id
left join auth_group_permissions grpp on grp.id = grpp.group_id
left join auth_permission perm on grpp.permission_id = perm.id
order by usr.id;

我发现我的权限设置不正确,并且还要注意django_content_type表,该表必须为每个应用和表添加每行添加,编辑,删除的行。因此,如果你有一个项目表,你应该在django_content_type中看到:

id           [generated by dB]
app_label    myApp
model        project

如果您遇到麻烦,另一个好主意就是启用并使用django管理应用。这将显示您的问题所在,通过设置一些测试权限,用户和组,您可以检查上面讨论的表,以查看插入的位置。这将使您了解身份验证权限的工作原理。

我写这个可能是为了节省一些人不必花费几个小时搞清楚我做了什么!