Django Rest Framework 视图集中的对象级授权

Object level authorization in a Django Rest Framework viewset

我正在使用 Django Rest Framework (DRF) 创建一个 API 并想知道我应该在哪里处理对象级授权。

到目前为止,我已经创建了一个 Organization 模型和一个自定义用户模型,其中电子邮件是唯一标识符而不是用户名。组织和用户目前通过多对多字段连接。

我想做的是确保当用户点击我的 API 时,他们只能对链接到用户各自组织的模型执行标准的 CRUD 操作。作为示例,这是我当前的 UserViewSet,我在其中重写了 get_queryset 方法,以将 User 查询集过滤为仅 return 与用户调用 API:

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer

    def get_queryset(self):
        User = get_user_model()
        user = self.request.user
        organizations = user.organization.all()
        return User.objects.filter(organization__in=organizations)

将这些限制扩展到其他视图集操作的最佳做​​法是什么?例如,如果我想确保用户只能创建其他用户并将其添加到他们链接到的组织中,我是否应该覆盖视图集中的 create 方法并在那里执行验证在请求中传递的数据是否与调用 API 的用户所属的组织相同?

我的直觉是我最终会以这种方式打破 DRY,因为我会覆盖所有视图集操作并重复几乎相同的覆盖。这个直觉错了吗?我想我可以将 "validations" 分成一个单独的 services.py 文件,并在覆盖操作中调用它们。我是否应该将这些检查卸载到自定义权限?或者我应该完全忽略视图并将验证放入序列化程序中?

实际上,您需要针对不同的 DRF CRUD 操作使用不同的工具。就个人而言,我喜欢使用 rules

  • name=XXX-list : /XXX/
    • list : 权限通过 get_queryset() 过滤
    • create :通过 rules 负载验证的权限 serializer
  • name=XXX-detail : /XXX/{id}
    • retrieve:权限通过get_queryset()过滤
    • partial_updateupdatedestroy:权限通过 rulesget_queryset()过滤

您可能需要编写自定义 DjangoObjectPermission class 来集成 rules