Skip to main content
 首页 » 编程设计

python之Django 守护者 : How to give all users the permissions of the anonymous user

2024年10月24日35yyy_WW

我正在使用 django-guardian 在我的 Django 项目中实现每个对象的权限。我遇到了注册用户无法查看匿名用户能够查看的对象的问题。我原以为如果匿名用户有权限,那么注册用户也应该有相同的权限(我无法想象我网站的一部分我希望匿名用户能够做某事而注册用户 不能做某事)。

from core.models import MyObject 
from django.contrib.auth.models import User 
from guardian.shortcuts import  
from guardian.utils import get_anonymous_user 
m = MyObject.objects.get(id=1) 
u = User.objects.get(username="MyUser") 
anon = get_anonymous_user() 
anon.has_perm('view_object', m) 
# ^ Prints True 
u.has_perm('view_object', m) 
# ^ Prints False 

在我的项目中,我有一些对象可以是“公共(public)”或“私有(private)”的。当用户将对象标记为“公共(public)”时,我将“view_object”权限授予匿名用户。我的 View 使用 PermissionRequiredMixin 进行保护,如下所示:

class MyObjectDetailsView(PermissionRequiredMixin, DetailView): 
    model = MyObject 
    permission_required = 'view_object' 

Django Guardian 是否提供某种方式来为注册用户提供与匿名用户相同的权限?或者如果用户没有权限但匿名用户有权限,也许有某种方法可以将 PermissionRequiredMixin 子类化以允许该操作?

请您参考如下方法:

我想出了一个解决方法,方法是像这样对 PermissionRequiredMixin 进行子类化:

from guardian.mixins import PermissionRequiredMixin 
from guardian.utils import get_anonymous_user 
 
 
class PermissionRequiredMixinWithAnonymous(PermissionRequiredMixin): 
    def check_permissions(self, request): 
        forbidden = super(PermissionRequiredMixinWithAnonymous, self).check_permissions(request) 
        if forbidden: 
            perms = self.get_required_permissions(request) 
            anon = get_anonymous_user() 
            obj = self.get_permission_object() 
            has_permissions = all(anon.has_perm(perm, obj) for perm in perms) 
            if has_permissions: 
                forbidden = None 
        return forbidden 

如果登录用户的权限检查失败(这是对 super() 的调用),那么检查基本上是对匿名用户重新运行。我将 if forbidden: block 中的代码基于 PermissionRequiredMixin.check_permissions 和 guardian.utils.get_403_or_None(后者从以前的)。我必须这样做,因为 check_permissions 和 get_403_or_None 都使用 request.user。