python - 基于方法的django rest框架 View 集权限

标签 python django django-rest-framework django-rest-viewsets

因此,我正在使用 DRF 编写我的第一个项目,但在为我的 View 集设置权限时遇到了一些问题。我已经使用 djangorestframework-jwt 进行身份验证。目前,我定义了几个不同的 ViewSet。我想做的是允许模型对象的所有者对该对象进行他们想要的任何更改,但阻止其他所有人(管理员除外)甚至查看该对象。基本上,我需要一种将权限类应用于特定方法的方法,以仅允许管理员查看“列表”、所有者“更新、销毁等”以及经过身份验证的用户“创建”。目前我有这样的东西:

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 IsOwner(permissions.BasePermission):
   def has_object_permissions(self, request, view, obj):
      return obj.owner == request.user.userprofile

我确信可以通过编写完全自定义的 View 来实现这一点,但我有一种直觉,认为有一种更简单的方法可以做到这一点,尤其是因为这基本上是我完成 API 必须做的最后一件事。感谢您的帮助,如果您需要更多信息,请告诉我。

最佳答案

我能够通过检查 View 中使用了哪个操作来创建权限类,如下所示:

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 返回 True 或方法未被覆盖时才会运行。

关于python - 基于方法的django rest框架 View 集权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45890657/

相关文章:

Python 3 Tkinter : How can I create a solid white line to partition widgets from the rest of the program?

javascript - Django Forms - 构建一个表单,显示来自多个不同模型的字段,但按外键排序

django-rest-framework - View 和 View 集之间的区别?

django - drf django rest auth如何过期或删除 token ?

python - 生成器不一定会产生任何东西

python - 根据最后一列累积 NumPy 数组的行

python - 检查 float 是否相等时无限循环

python - 从 Django (PyDev) 中的 my_app.views 导入基本的、 Unresolved 问题

python - Django ListData 在 DetailView 上从数组

python - 使用 python 3 在 Windows 10 上运行服务器时出现 django 404 错误