我有这样的模特:
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
的内容。
也许我只是在思考它而我应该只使用自定义查询集而不是使用权限?
答案 0 :(得分:5)
official documentation建议在此用例中使用自定义get_queryset
方法,这正是我要做的。
权限对象的has_object_permission
仅在单个对象的视图上调用时才会运行,因此不会对列表视图强制执行权限。
基本上,您不是试图允许或拒绝访问,而是尝试过滤结果。在数据库级别上过滤是最快,最简单,最安全(最不容易出错)的选项。权限框架仅用于允许或拒绝对对象或完整对象组的访问,不会过滤特定响应的内容。 get_queryset
方法用于过滤特定响应的内容,应该这样使用。