使用 DjangoObjectPermissionsFilter 使用 django-guardian 过滤用户对象
Using DjangoObjectPermissionsFilter to filter objects of user using 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,)
预期行为
EventViewSet.list
返回的Events
列表仅包含请求用户可以查看的对象(请求用户具有django.authview_event
权限或('view_event', event_object)
.
EventViewSet.details
returns Event
实例仅当请求用户具有 view_event
权限或 ('view_event', event_object)
权限时。
实际行为
- 如果用户有django auth权限
view_event
和guardian权限('view_event', event_obj)
,可以访问路由list
(获取所有条目)和details
关联event_obj
.
- 如果用户没有授权权限
view_event
,但有监护人权限 ('view_event', event_obj)
,他们在所有路由中都会收到 403(包括与关联的 details
路由他们有权访问的event_obj)。
- 如果用户有
view_event
但没有 ('view_event', event_obj)
,他们可以访问路由 list
(查看所有条目),但他们在 [=28] 中收到 404 =] 路由,不管访问的条目是什么。
谢谢!
好的,事实证明所有具有 class DjangoObjectPermissions
权限的视图将只允许用户查看给定的资源,前提是他们具有 模型级和对象级 权限。事实上,我的用户能够列出所有对象,但不能检索其中任何对象,这是因为 known bug 已经更正但尚未在当前版本中。
我能够将 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,)
预期行为
EventViewSet.list
返回的Events
列表仅包含请求用户可以查看的对象(请求用户具有django.authview_event
权限或('view_event', event_object)
.EventViewSet.details
returnsEvent
实例仅当请求用户具有view_event
权限或('view_event', event_object)
权限时。
实际行为
- 如果用户有django auth权限
view_event
和guardian权限('view_event', event_obj)
,可以访问路由list
(获取所有条目)和details
关联event_obj
. - 如果用户没有授权权限
view_event
,但有监护人权限('view_event', event_obj)
,他们在所有路由中都会收到 403(包括与关联的details
路由他们有权访问的event_obj)。 - 如果用户有
view_event
但没有('view_event', event_obj)
,他们可以访问路由list
(查看所有条目),但他们在 [=28] 中收到 404 =] 路由,不管访问的条目是什么。
谢谢!
好的,事实证明所有具有 class DjangoObjectPermissions
权限的视图将只允许用户查看给定的资源,前提是他们具有 模型级和对象级 权限。事实上,我的用户能够列出所有对象,但不能检索其中任何对象,这是因为 known bug 已经更正但尚未在当前版本中。