使用DjangoObjectPermissionsFilter使用django-guardian

时间:2015-07-30 00:39:49

标签: django-rest-framework django-guardian

我能够将django-guardian和我的django-rest-framework项目设置为example in drf docs,但我无法实现我想要的行为。有人可以指出,如果我做错了什么或者我想做什么不能用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,)

预期行为

  • Events返回的EventViewSet.list列表仅包含请求用户可以查看的对象(请求用户具有django.auth view_event权限或('view_event', event_object)
  • 仅当请求用户具有EventViewSet.details权限或Event权限时,
  • view_event才会返回('view_event', event_object)个实例。

实际行为

  • 如果用户拥有django身份验证权限view_event和监护人权限('view_event', event_obj),则可以访问路由list(获取所有条目)和detailsevent_obj
  • 如果用户没有auth权限view_event,但拥有监护人权限('view_event', event_obj),则他们会在所有路由中收到403(包括与event_obj关联的details路由他们有权获得许可。)
  • 如果用户有view_event但没有('view_event', event_obj),则他们可以访问路由list(查看所有条目),但他们会在details中收到404路线,无论进入的是什么条目。

谢谢!

1 个答案:

答案 0 :(得分:5)

好的,事实证明,具有权限类DjangoObjectPermissions的所有视图只允许用户查看给定资源(如果他们具有模型级别和对象级别权限)。我的用户能够列出所有对象但没有检索到任何对象的事实是因为known bug已经得到纠正但尚未在当前版本上进行。