我正在使用Django Rest Framework(DRF(创建一个API,并想知道在哪里应该处理对象级别的授权。
到目前为止,我已经创建了一个Organization
模型和一个自定义用户模型,其中电子邮件是唯一标识符,而不是用户名。组织和用户目前通过多对多字段进行连接。
我想做的是确保当用户点击我的API时,他们只能对链接到用户各自组织的模型执行标准的CRUD操作。作为一个示例,这里是我当前的UserViewSet
,其中我覆盖了get_queryset
方法来过滤User
查询集,以仅返回与调用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,因为我会覆盖所有视图集操作,并重复几乎相同的覆盖。这种直觉错了吗?我想我可以将"验证"分离到一个单独的services.py
文件中,并在overriden操作中调用它们。我应该将这些检查卸载到自定义权限吗?或者我应该完全忽略视图并将验证放入序列化程序中?
实际上,您需要不同的工具来执行不同的DRF CRUD操作。就我个人而言,我喜欢使用rules
包
name=XXX-list
:/XXX/
list
:通过get_queryset()
筛选的权限create
:通过rules
和使用serializer
进行有效负载验证的权限
name=XXX-detail
:/XXX/{id}
retrieve
:通过get_queryset()
筛选的权限partial_update
、update
和destroy
:通过rules
和get_queryset()
筛选的权限
您可能需要编写一个自定义的DjangoObjectPermission
类来集成rules