Django-REST框架:将过滤器应用于列表视图,而不是detail-vi

2024-09-28 22:39:32 发布

您现在位置:Python中文网/ 问答频道 /正文

对于Django-REST框架,当使用ModelViewSet时,有没有一种方法可以只过滤列表结果而不过滤详细结果?在

我有一个拥有所有者的对象列表,我只希望用户在访问对象列表时看到他们拥有的对象。为此,我基于rest_framework.filters.BaseFilterBackend实现了一个新的过滤器后端,它对列表很好。在

当我试图访问一个不属于我的用户的对象时,问题就出现了:我得到的是“404notfound”而不是“403forbidden”。在

换句话说,过滤似乎不仅应用于列表,还应用于详细信息视图。有没有一种方法可以改变这一点,使我在访问一个无权查看的对象时得到预期的403?在

我已经有了一个permission类,它可以防止用户看到他不拥有的对象,但它甚至不会被调用,除非我注释掉viewset类上的filter_backends属性。在

另一种考虑这一点的方法是,我只想列出用户有权查看的对象。在


Tags: 对象django方法用户框架视图rest过滤器
2条回答

您想要引发的rest_framework异常是PermissionDenied返回一个403,所以请这样做而不是get_object_or_404。在

应用所需的逻辑,并在用户不应位于该DetailView端点时引发异常。在

from rest_framework.exceptions import PermissionDenied

class UserViewSet(viewsets.ViewSet):

    model = User

    def retrieve(self, request, pk=None):
        try:
            return self.model.objects.filter(foo='bar').get(pk=pk)
        except User.DoestNotExist:
            # can't find the User based upon the filter foo='bar'
            # that represents a object permissions filter
            raise PermissionDenied("message to accompany the 403 error if desired")

您可以检查一下pk是否在kwargs视图中

class MyFilterBackend(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        if 'pk' not in view.kwargs:
            queryset = queryset.filter(...)
        return queryset

相关问题 更多 >