基于方法的django rest框架视图集权限
django rest framework viewset permission based on method
所以我正在用 DRF 编写我的第一个项目,但在为我的视图集设置权限时遇到了一些问题。我已经使用 djangorestframework-jwt 进行身份验证。目前,我定义了几个不同的 ViewSet。我想做的是允许模型对象的所有者对该对象进行他们想要的任何更改,但阻止其他所有人(管理员除外)甚至查看该对象。基本上,我需要一种将权限 classes 应用于特定方法的方法,以仅允许管理员查看 'list'、所有者 'update, destroy, etc' 和经过身份验证的用户 'create'。目前我有这样的东西:
class LinkViewSet(viewsets.ModelViewSet):
queryset = Link.objects.all()
serializer_class = LinkSerializer
模特
class Link(models.Model):
name = models.CharField(max_length=200)
url = models.URLField()
# another model with a OneToMany relationship
section = models.ForeignKey('homepage.LinkSection', related_name='links', on_delete=models.CASCADE
owner = models.ForeignKey('homepage.UserProfile'), related_name='links', on_delete=models.CASCADE)
以及我要申请的权限class
class IsOwner(permissions.BasePermission):
def has_object_permissions(self, request, view, obj):
return obj.owner == request.user.userprofile
我确信可以通过编写完全自定义的视图来实现这一点,但我有一种直觉,认为有一种更简单的方法可以做到这一点,尤其是因为这基本上是我完成 API。感谢您的帮助,如果您需要更多信息,请告诉我。
我能够通过检查视图中使用了哪个操作来创建权限 class,如下所示:
class IsOwner(permissions.BasePermission):
'''
Custom permission to only give the owner of the object access
'''
message = 'You must be the owner of this object'
def has_permission(self, request, view):
if view.action == 'list' and not request.user.is_staff:
print('has_permission false')
return False
else:
print('has_permission true')
return True
def has_object_permission(self, request, view, obj):
print('enter has_object_permission')
# only allow the owner to make changes
user = self.get_user_for_obj(obj)
print(f'user: {user.username}')
if request.user.is_staff:
print('has_object_permission true: staff')
return True
elif view.action == 'create':
print('has_object_permission true: create')
return True
elif user == request.user:
print('has_object_permission true: owner')
return True # in practice, an editor will have a profile
else:
print('has_object_permission false')
return False
def get_user_for_obj(self, obj):
model = type(obj)
if model is models.UserProfile:
return obj.user
else:
return obj.owner.user
get_user_for_obj
专门用于我作为辅助方法的实现,因为我的模型在如何获取用户实例方面不一致。你不想让 has_permission
过于严格,因为 has_object_permission
只会 运行 如果 has_permission
returns True 或者如果方法没有被覆盖。
所以我正在用 DRF 编写我的第一个项目,但在为我的视图集设置权限时遇到了一些问题。我已经使用 djangorestframework-jwt 进行身份验证。目前,我定义了几个不同的 ViewSet。我想做的是允许模型对象的所有者对该对象进行他们想要的任何更改,但阻止其他所有人(管理员除外)甚至查看该对象。基本上,我需要一种将权限 classes 应用于特定方法的方法,以仅允许管理员查看 'list'、所有者 'update, destroy, etc' 和经过身份验证的用户 'create'。目前我有这样的东西:
class LinkViewSet(viewsets.ModelViewSet):
queryset = Link.objects.all()
serializer_class = LinkSerializer
模特
class Link(models.Model):
name = models.CharField(max_length=200)
url = models.URLField()
# another model with a OneToMany relationship
section = models.ForeignKey('homepage.LinkSection', related_name='links', on_delete=models.CASCADE
owner = models.ForeignKey('homepage.UserProfile'), related_name='links', on_delete=models.CASCADE)
以及我要申请的权限class
class IsOwner(permissions.BasePermission):
def has_object_permissions(self, request, view, obj):
return obj.owner == request.user.userprofile
我确信可以通过编写完全自定义的视图来实现这一点,但我有一种直觉,认为有一种更简单的方法可以做到这一点,尤其是因为这基本上是我完成 API。感谢您的帮助,如果您需要更多信息,请告诉我。
我能够通过检查视图中使用了哪个操作来创建权限 class,如下所示:
class IsOwner(permissions.BasePermission):
'''
Custom permission to only give the owner of the object access
'''
message = 'You must be the owner of this object'
def has_permission(self, request, view):
if view.action == 'list' and not request.user.is_staff:
print('has_permission false')
return False
else:
print('has_permission true')
return True
def has_object_permission(self, request, view, obj):
print('enter has_object_permission')
# only allow the owner to make changes
user = self.get_user_for_obj(obj)
print(f'user: {user.username}')
if request.user.is_staff:
print('has_object_permission true: staff')
return True
elif view.action == 'create':
print('has_object_permission true: create')
return True
elif user == request.user:
print('has_object_permission true: owner')
return True # in practice, an editor will have a profile
else:
print('has_object_permission false')
return False
def get_user_for_obj(self, obj):
model = type(obj)
if model is models.UserProfile:
return obj.user
else:
return obj.owner.user
get_user_for_obj
专门用于我作为辅助方法的实现,因为我的模型在如何获取用户实例方面不一致。你不想让 has_permission
过于严格,因为 has_object_permission
只会 运行 如果 has_permission
returns True 或者如果方法没有被覆盖。