如何在django-rest-framework中设置权限,以便会话用户只能列出具有该用户外键的对象?

时间:2014-05-03 16:41:06

标签: python django django-rest-framework

我有这样的模特:

class TheModel(models.Model):
    name = models.CharField(max_length=10)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL)

我想创建一个API视图,其中列出TheModel等于TheModel.owner的所有request.user个对象。

我认为我可以通过覆盖get_queryset来实现此目的,但似乎我应该使用自定义BasePermission。问题是它看起来不像BasePermission.has_object_permission在列表视图中的每个对象上运行。唯一可以运行的是BasePermission.has_permission。我用这个测试了这个: -

class TheModelViewSet(viewsets.ModelViewSet):
    model = TheModel
    permission_classes = [IsOwner]

class IsOwner(permissions.BasePermission):
    def has_permission(self, request, view):
        print("checking has permission for {}".format(request.user))
        return True

    def has_object_permission(self, request, view, obj):
        print("checking permission for {} on {}").format(request.user, obj.user)

        return obj.owner == request.user

唯一可以打印的是来自IsOwner.has_permission的内容。

也许我只是在思考它而我应该只使用自定义查询集而不是使用权限?

1 个答案:

答案 0 :(得分:5)

official documentation建议在此用例中使用自定义get_queryset方法,这正是我要做的。

权限对象的has_object_permission仅在单个对象的视图上调用时才会运行,因此不会对列表视图强制执行权限。

基本上,您不是试图允许或拒绝访问,而是尝试过滤结果。在数据库级别上过滤是最快,最简单,最安全(最不容易出错)的选项。权限框架仅用于允许或拒绝对对象或完整对象组的访问,不会过滤特定响应的内容。 get_queryset方法用于过滤特定响应的内容,应该这样使用。