我的模特:
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)
我正在使用基于类的视图。我想根据“位置”值授予访问不同视图的权限。我找到了许多解决方案,但现在我有些困惑。做我想做的最好的方法是什么?
答案 0 :(得分:1)
我会使用自定义装饰器。您可以使用@method_decorator(decorator, name='dispatch')
。首先,您将在app目录中创建一个decorators.py文件。几乎发生的是方法装饰器在视图之前被调用,并将函数传递给第一个可调用对象。我们实际上所做的是将可调用对象作为位置检查进行调用,并传递position参数。然后,我们处理实际的方法装饰器部分,该部分在_method_wrapper中传递了函数参数。此时,我们就像在视图中使用_wrapper可调用对象中的request变量那样进行计算。
# 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")
)