我正在使用django-guardian在我的Django项目中实现每个对象的权限。我遇到了注册用户无法查看匿名用户可以查看的对象的问题。我原以为如果匿名用户有权限,那么注册用户应该拥有相同的权限(我无法想象我的网站的一部分,我希望匿名用户能够做某事和注册用户< em>不能够做某事)。
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
在我的项目中,我有一些可以&#34;公共&#34;或者&#34;私人&#34;。当用户将对象标记为&#34; Public&#34;时,我授予&#34; view_object&#34;对匿名用户的许可。我的观点使用PermissionRequiredMixin
进行保护,如下所示:
class MyObjectDetailsView(PermissionRequiredMixin, DetailView):
model = MyObject
permission_required = 'view_object'
Django Guardian是否提供某种方式为注册用户提供与匿名用户相同的权限?或者也许有一些方法可以将PermissionRequiredMixin子类化为允许操作,如果用户没有权限但是匿名用户呢?
答案 0 :(得分:1)
我通过子类化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:
上的PermissionRequiredMixin.check_permissions
块和guardian.utils.get_403_or_None
(后者从前者调用)。我必须这样做,因为check_permissions
和get_403_or_None
都使用request.user
。