Django - 装饰器限制 "staff"

3
我的目标是限制对“员工组”的访问。我正在尝试使用decorators.py实现此目标,但这样做会限制我注册的每个用户,而不仅仅是员工。当我用管理员登录时,它会给我“您未经授权”,这应该只针对“员工”,他们应该只能看到平台的一个模板。
这是我的管理页面的图片。

users

staff users

users core/decorators.py

from django.http import HttpResponse
from django.shortcuts import redirect

def allowed_user(allowed_roles=[]):
    def decorator(view_func):
        def wrapper_func(request, *args, **kwargs):

            group = None
            if request.user.groups.exists():
                group = request.user.groups.all()

            if group in allowed_roles:
                return view_func(request, *args, **kwargs)

            else:
                return HttpResponse(' You are not Authorized!')
        return wrapper_func
    return decorator

core/views.py

from django.shortcuts import render, get_object_or_404
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.list import ListView
from .decorators import allowed_user

# Create your views here.
from quiz.models import Questions
from jobs.models import post_job




@allowed_user(allowed_roles=['Admin, Students'])
def homepage(request):
    return render(request, 'core/homepage.html')

 @allowed_user(allowed_roles=['Admin, Students'])
def userProfileView(request, username):
    user= get_object_or_404(User, username=username)
    jobs = post_job.objects.all()
    categories = Questions.CAT_CHOICES
    scores = []
    for category in categories:
        score = Questions.objects.filter(category=category[0], student= user).count()
        scores.append(score)

    context = {

    'user' : user, 'categories_scores' : zip( categories,scores),
    'jobs': jobs



    }
    return render(request, 'core/user_profile.html' , context)



class UserList(LoginRequiredMixin, ListView):
    model = User
    template_name = 'core/users.html'

account/views.py

from django.shortcuts import render, HttpResponseRedirect
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from accounts.forms import FormRegistrazione
from .decorators import allowed_user

# Create your views here.

def registrazioneView(request):
    if request.method == "POST":
        form = FormRegistrazione(request.POST)
        if form.is_valid():
            username = form.cleaned_data["username"]
            email = form.cleaned_data["email"]
            password = form.cleaned_data["password1"]
            User.objects.create_user(username=username, password=password, email=email)
            user = authenticate(username=username, password=password)
            login(request, user)
            return HttpResponseRedirect("/")


    else:
        form = FormRegistrazione()
    context = {"form": form}
    return render(request, 'accounts/registrazione.html', context)
1个回答

5

您的allowed_roles是字符串,因此group in allowed_roles将始终为false,特别是因为groupGroupQuerySet集合。该集合可以包含零个、一个或多个组。

您可以使用request.user.groups.filter(name__in=allowed_roles).exists()来检查组是否存在,因此装饰器如下所示:

from functools import wraps

def allowed_user(allowed_roles=()):
    def decorator(view_func):
        @wraps(view_func)
        def wrapper_func(request, *args, **kwargs):
            if request.user.groups.<b>filter(name__in=allowed_roles)</b>.exists():
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse('You are not Authorized!')
        return wrapper_func
    return decorator

感谢您的贡献!这几天以来,我一直很难理解这个过程。如果我把这段代码放在装饰器中,并且在我的views.py文件中保留@allowed_user(allowed_roles=['Admin, Students']),那么我会得到“name 'wraps' is not defined”的错误提示。 - mattiazm
@mattiazm:是的,你需要导入它,这是functools模块中的一个函数。 - Willem Van Onsem
好的,完美的,所以基本上我导入functools import wraps,然后在我的views.py上留下@allowed_user(allowed_roles=['admin, students']),就可以工作了? - mattiazm
@mattiazm:是的。但我强烈建议测试一下,因为我可能误解了你问题的某些部分 :) - Willem Van Onsem

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