【发布时间】:2020-05-05 18:32:05
【问题描述】:
在我的项目中,我同时拥有基于组和自定义用户的权限。
我有一个自定义身份验证后端,它主要检查用户是否具有组权限,然后查看他们是否有任何需要从检查的权限中删除的撤销权限。
现在我正在测试所述撤销权限的实现,我遇到了一个优化问题,因为我的 CustomUser 模型有一个 M2M 字段来保存这些与auth_permissions 相关的撤销权限,我的 BackendAuthentication 会检查它,我在页面加载时获得了疯狂的数据库点击量。
如何将预取的对象传递给我的 AuthBackend?
这是我的 AuthBackend:
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import Permission
class UsersAuthenticationBackend(ModelBackend):
def _get_revoked_perms(self, user_obj):
if user_obj.is_superuser or user_obj.is_admin:
revoked_perms = Permission.objects.none()
elif hasattr(user_obj, 'revoked_permissions'):
# this causes the issue, I need to pass in the prefetch related to my model backend...HOW?
# this should be something like CustomUser.objects.prefetch_related('revoked_permissions')
revoked_perms = getattr(user_obj, 'revoked_permissions').values_list('content_type__app_label', 'codename')
else:
revoked_perms = Permission.objects.none()
revoked_perms = ["{}.{}".format(perm[0], perm[1]) for perm in revoked_perms]
print(revoked_perms)
return revoked_perms
def has_perm(self, user_obj, perm, obj=None):
if not user_obj.is_active:
return False
revoked_perms = self._get_revoked_perms(user_obj)
all_perms = self.get_all_permissions(user_obj)
allowed_perms = [p for p in all_perms if not p in revoked_perms]
if isinstance(perm, str):
return perm in allowed_perms
elif isinstance(perm, Permission):
return '{}.{}'.format(perm.content_type.app_label, perm.codename) in allowed_perms
else:
return False
这里是CustomUser的相关部分,如果你需要看的话
class CustomUser(AbstractUser, SafeDeleteModel):
...
revoked_permissions = models.ManyToManyField(Permission, blank=True)
【问题讨论】:
标签: django python-3.x django-authentication django-permissions