问题描述
我想创建一个权限(或实现相同目的的权限),该权限可以有选择地应用于所有用户,包括超级用户。
我可以很容易地创建自定义权限:
ct = ContentType.objects.get_for_model(MyModel)
Permission.objects.create(
name='optional permission',codename='optional_permission,content_type=ct)
但是,对于超级用户user.has_perm('my_app_label.optional_permission')
我的用例是:
我想创建一个查询集管理器函数,该函数仅为已应用optional_permission
的组中的用户返回草稿文章。我希望超级用户可以免去看这些草稿的要求。
解决方法
您可以尝试通过向原始实现中传递一个额外的关键字参数来覆盖has_perm
。
class User(AbstractUser):
...
def has_perm(self,perm,obj=None,superuser_exempt=True):
# Active superusers have optional permissions.
if superuser_exempt:
if self.is_active and self.is_superuser:
return True
# Otherwise we need to check the backends.
return _user_has_perm(self,obj)
看看has_perm
源代码:
class PermissionMixin:
def has_perm(self,obj=None):
"""
Return True if the user has the specified permission. Query all
available auth backends,but return immediately if any backend returns
True. Thus,a user who has permission from a single auth backend is
assumed to have permission in general. If an object is provided,check
permissions for that object.
"""
# Active superusers have all permissions.
if self.is_active and self.is_superuser:
return True
# Otherwise we need to check the backends.
return _user_has_perm(self,obj)
AbstractUser
从has_perm
继承了PermissionMixin
方法
class AbstractUser(AbstractBaseUser,PermissionsMixin):
...
,
最后我不得不实施一个稍微丑陋的解决方法,因此有兴趣知道某人是否可以做得更好。
我必须在用户模型上为超级用户添加一个覆盖布尔值
class User(AbstractUser):
superuser_view_draft_override = models.BooleanField(
default=False,help_text='This allows us to toggle the \'see draft\' permission for superusers only')
@cached_property
def can_see_draft_content(self):
# Have to use the boolean override for superusers because they
# have all permissions turned on by default
if self.is_superuser:
return self.superuser_view_draft_override
# Otherwise use the permission...
return self.has_perm('my_app_label.optional_permission')