使用DjangoObjectPermissionsFilter和django-guardian过滤用户对象的方法

5
我能够设置django-guardian和我的django-rest-framework项目,如在drf文档的示例中,但我未能实现我想要的行为。请问是否有人能指出我是否做错了什么或者我想要的不能用guardian实现?

设置

settings.py

INSTALLED_APPS = (
    ...
    'guardian',
    'simple',
)

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'guardian.backends.ObjectPermissionBackend',
)

'DEFAULT_PERMISSION_CLASSES': (
    'infrastructure.permissions.DjangoObjectPermissions',
)

infrastructure.permissions.py

from rest_framework import permissions


class DjangoObjectPermissions(permissions.DjangoObjectPermissions):
    """
    Similar to `DjangoObjectPermissions`, but adding 'view' permissions.
    """
    perms_map = {
        'GET': ['%(app_label)s.view_%(model_name)s'],
        'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
        'HEAD': ['%(app_label)s.view_%(model_name)s'],
        'POST': ['%(app_label)s.add_%(model_name)s'],
        'PUT': ['%(app_label)s.change_%(model_name)s'],
        'PATCH': ['%(app_label)s.change_%(model_name)s'],
        'DELETE': ['%(app_label)s.delete_%(model_name)s'],
    }

models.py

class Event(models.Model):
    name = models.CharField(max_length=255)
    min_age = models.IntegerField()

    def __str__(self):
        return self.name

    class Meta:
        permissions = (('view_event', 'Can view event'),)

views.py

class EventViewSet(viewsets.ModelViewSet):
    queryset = models.Event.objects.all()
    serializer_class = serializers.EventSerializer
    filter_backends = (filters.DjangoObjectPermissionsFilter,)

期望行为:
- EventViewSet.list 返回的Events列表仅包含请求用户可以查看的对象(请求用户具有django.auth view_event 权限或 ('view_event', event_object)权限)。 - EventViewSet.details 仅在请求用户具有view_event('view_event', event_object)权限时返回Event实例。
实际行为:
- 如果用户具有django.auth权限 view_event 和guardian权限('view_event', event_obj),则可以访问与event_obj相关联的list(获取所有条目)和details路由。 - 如果用户没有auth权限view_event,但具有guardian权限('view_event', event_obj),则他们在所有路由中都会收到403的错误提示(包括他们有权限访问的event_obj相关的details路由)。 - 如果用户具有view_event但没有('view_event', event_obj),则他们可以访问list路由(查看所有条目),但无论所访问的条目是什么,访问details路由时都会收到404的错误提示。
感谢您!

我开始尝试使用Guardian,发现了相同的行为。但是我还没有尝试过filter_backends,所以我会试一下。 - Aldo 'xoen' Giambelluca
1个回答

6

好的,事实证明,所有使用DjangoObjectPermissions权限类的视图只有在用户拥有模型级别和对象级别权限时才允许其查看给定资源。我的用户可以列出所有对象但无法检索它们的原因是由于已知的错误,该错误已经被纠正,但目前还没有包含在当前版本中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接