当前在DRF中根据用户类型查看权限的最佳方式是什么?在我的结构中有几个user_types
,例如TEAM_LEADER
不能创建team
对象,但可以看到teams
的列表。这意味着对于同一个类视图,我希望使用不同的权限进行POST和GET。我希望尽可能干地做这件事,并试图遵循瘦视胖模型的设计原则(也想知道这是否是2021年的好做法(。
models.py用于用户模型
class User(AbstractBaseUser):
...fields here
objects = UserManager()
USERNAME_FIELD = "email"
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
if perm.Meta.verbose_name=="worksite" and perm.request.method =="POST":
if self.user_type <= self.DEPARTMENT_MANAGER:
return True
else:
return False
return True
视图.py
class DashboardPermissions(BasePermission):
message="You dont have permission for this action"
def has_permission(self, request, view):
return request.user.has_perm(view.Meta.verbose_name)
class ViewName(CreateAPIView):
permission_classes = (IsAuthenticated,DashboardPermissions)
authentication_classes = ()
serializer_class = WorksiteSerializer
queryset = Worksite.objects.all()
class Meta:
verbose_name="view_name"
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
奖金问题我的解决方案会产生任何性能问题吗?
创建自定义Permission
类是一种很好的做法。所以这部分在我看来还可以。我们可以讨论逻辑应该在权限还是用户中(就像你做的那样(,但这没什么大不了的。
如果您希望对视图中的不同端点拥有不同的权限,只需覆盖get_permissions
方法即可。
# Inherited method from APIView
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]
正如您所看到的,对于ALL服务,它将从self.permission_classes
获取权限。
要在GET/CREATE之间使用不同的权限,可以创建endpoint: [...permissions]
的dict
,并覆盖get_permissions
以获取与当前操作匹配的权限
permissions = {
"create": [P1, P2,],
"get": [P1,]
}
def get_permissions(self):
action = self.it_is_somewhere_in_there
return [permission() for permissions in self.permissions[action]]
@JordanKowal的回答是正确的,但正如评论中所提到的,
然后我会经常重复权限dict吗?为了做到这一点,每一类视图的权利
为此,您可以创建一个mixin类。它本质上允许您将要在多个视图中复制的一些代码/功能移动到一个独立的类中,并根据您的方便从中继承。
为了扩展Jordan的答案,以下是混合类的样子:
class DefaultPermissionsMixin(object):
permissions = {
"create": [IsAuthenticated, DashboardPermissions],
"get": [DashboardPermissions]
}
def get_permissions(self):
# default `get_permissions` method
# reads `self.permission_classes`
perms = super().get_permissions()
if self.action in self.permissions.keys():
return perms + [p() for p in self.permissions[self.action]]
else:
return perms
class View1(CreateAPIView, DefaultPermissionsMixin):
# ...snip...
class View2(CreateAPIView, DefaultPermissionsMixin):
# i can overwrite here per my convenience
permissions = {
"create": [DashboardPermissions],
"delete": [],
}
# i can also define permissions the default way
# that will be enabled on all actions
permission_classes = [IsAuthenticated]
# ...snip...