Django REST框架:将过滤器应用于列表视图但不应用详细视图

时间:2016-01-19 23:44:26

标签: python django rest django-rest-framework

使用Django REST Framework时,有一种方法可以在使用ModelViewSet时仅过滤列表结果而不过滤详细结果吗?

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

当我尝试访问不属于我的用户的对象时出现问题:我收到“404 not found”而不是“403 forbidden”。

换句话说,过滤似乎不仅适用于列表,还适用于详细视图。有没有办法改变这一点,以便在访问我无权查看的对象时获得预期的403?

我已经有了一个权限类,它阻止用户看到他不拥有的对象,但除非我在视图集类上注释掉filter_backends属性,否则它甚至都不被调用。

另一种思考方式是我只想列出用户有权查看的对象。

2 个答案:

答案 0 :(得分:0)

您要引发的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")

答案 1 :(得分:0)

您可以查看pk是否在视图kwargs

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