首页 > 解决方案 > Django Rest Framework check_object_permissions 未被调用

问题描述

我试图确保用户有权查看他们正在调用的对象。这是我的权限类:

from rest_framework import permissions


class IsOwner(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to do actions.
    """
    message = 'You must be the owner of this object.'

    def has_object_permission(self, request, view, obj):
        print("CHECK THAT I GOT HERE")
        return obj.user == request.user

这是我的视图集:

class TopLevelJobViewSet(ModelViewSet):
    permission_classes = (IsOwner,)
    serializer_class = TopLevelJobSerializer
    queryset = TopLevelJob.objects.all()
    filter_backends = [DjangoFilterBackend, RelatedOrderingFilter]
    filter_class = TopLevelJobFilter
    ordering_fields = '__all__'

没有被调用,任何访问端点的has_object_permissions人都可以访问所有对象。

为什么是这样?我怎样才能has_object_permissions被叫到?

这篇文章:Django rest framework ignores has_object_permission谈论它是一个没有GenericAPIView. 但ModelViewSetGenericViewSet哪个有generics.GenericAPIView。有什么东西在某个地方覆盖了这个吗?

编辑:我的问题是我打电话list而不是get. 我怎样才能只返回list属于用户的对象?

这个链接:https ://www.django-rest-framework.org/api-guide/filtering/#filtering-against-the-current-user表明我可以实现这样的东西:

def get_queryset(self):
    username = self.kwargs['username']
    return Purchase.objects.filter(purchaser__username=username)

如果我必须将它添加到每个视图集中,这似乎违反了 DRY。有没有办法把它变成permissions我可以随时调用的课程?

标签: djangopython-3.xdjango-rest-framework

解决方案


您可以实现自定义通用过滤 [drf-doc]。例如:

class IsOwnerFilter(filters.BaseFilterBackend):

    def filter_queryset(self, request, queryset, view):
        return queryset.objects.filter(user=request.user)

然后您可以将其添加到您的ModelViewSet

class TopLevelJobViewSet(ModelViewSet):
    permission_classes = (IsOwner,)
    serializer_class = TopLevelJobSerializer
    queryset = TopLevelJob.objects.all()
    filter_backends = [IsOwnerFilter, DjangoFilterBackend, RelatedOrderingFilter]
    filter_class = TopLevelJobFilter
    ordering_fields = '__all__'

推荐阅读