组权限连接模型列表

Group permission connected to model list

我的模特:

class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)

POSITIONS = (
    ("volunteer", "volunteer"),
    ("employee", "employee"),
    ("manager", "manager"),
    ("director", "director"),
    ("vet", "vet")
)
position = models.CharField(choices=POSITIONS, max_length=15)
picture = models.ImageField(blank=True, null=True)

我正在使用基于 class 的视图。我想根据 'position' 值授予访问不同视图的权限。我找到了十几种解决方案,现在我有点困惑。做我想做的事情的最佳方法是什么?

我会使用自定义装饰器。你可以使用@method_decorator(decorator, name='dispatch')。首先,您将在 app 目录中创建一个 decorators.py 文件。几乎发生的事情是在视图之前调用方法装饰器并将函数传递给第一个可调用对象。我们实际做的是将可调用对象设为位置检查并传递位置参数。然后我们处理在 _method_wrapper 中传递函数参数的实际方法装饰器部分。在这一点上,我们进行计算,就像我们在视图中使用 _wrapper 可调用变量中的请求变量一样。

# decorators.py
from django.core.exceptions import PermissionDenied
from app.models import UserProfile

def position_check(position):
    def _method_wrapper(function):
        def _wrapper(request, *args, **kwargs):
            try:
                user = UserProfile.object.get(user_id=request.user.id)
            except UserProfile.DoesNotExist:
                raise PermissionDenied
            if user.position == position:
                return function(request, *args, **kwargs)
            else:
                raise PermissionDenied
        return _wrapper
    return _method_wrapper

现在在你看来你会这样称呼它。

# views.py
from app.decorators import position_check
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

@method_decorator(position_check('manager'), name='dispatch')
class HomeView(TemplateView):
    template_name = "home.html"

我认为您 运行 遇到的唯一问题是需要继承权限。我不会按照你的选择来设置你的选择。我会将实际值设置为一个数字,并将选择部分设置为您的人类可读性,如下所示。这将允许您根据数字值设置权限,因此 if user.position >= 3 主管随后将从经理那里继承权限。

POSITIONS = (
    (1, "volunteer"),
    (2, "employee"),
    (3, "manager"),
    (4, "director"),
    (5, "vet")
)