[英]Django REST Framework: apply filter to list view but not detail view
With Django REST Framework is there a way, when using a ModelViewSet
, to filter only the list results but not the detail results? 使用Django REST Framework时,有没有一种方法,当使用ModelViewSet
,仅过滤列表结果而不过滤详细结果?
I have a list of objects that have an owner and I only want users to see the objects they own when they access the objects list. 我有一个拥有所有者的对象列表,我只希望用户在访问对象列表时看到他们拥有的对象。 For that purpose I implemented a new filter backend based on rest_framework.filters.BaseFilterBackend
, which works fine for the list. 为此,我基于rest_framework.filters.BaseFilterBackend
实现了一个新的过滤器后端,该过滤器在列表中可以正常使用。
The problem arises when I try to access an object that doesn't belong to my user: I get a "404 not found" instead of a "403 forbidden". 当我尝试访问不属于我的用户的对象时,就会出现问题:我收到“找不到404”而不是“ 403禁止”。
In other words, filtering seems to be applied not only to the list but also to the detail view. 换句话说,过滤似乎不仅应用于列表,而且还应用于细节视图。 Is there a way to change this, so that I get the expected 403 when accessing an object which I'm not authorized to see? 有没有一种方法可以更改此设置,以便在访问未经授权查看的对象时得到预期的403?
I already have a permission class in place which prevents a user from seeing objects he doesn't own but it's not even being called unless I comment out the filter_backends
property on the viewset class. 我已经有一个权限类,可以防止用户看到他不拥有的对象,但是除非我在viewset类上注释掉filter_backends
属性,否则它甚至不会被调用。
Another way to think about this is that I only want to list objects that the user has permission to see. 考虑这种情况的另一种方法是,我只想列出用户有权查看的对象。
The rest_framework
exception that you'd want to raise is PermissionDenied
to return a 403 , so do this instead of get_object_or_404
. 您要引发的rest_framework
异常是PermissionDenied
以返回403 ,因此请执行此操作,而不是get_object_or_404
。
Apply the logic you want, and raise the exception when the User should not be at that DetailView endpoint. 应用所需的逻辑,并在User不应该位于该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")
You could check to see if pk
is in the view kwargs 您可以检查pk
是否在视图kwargs中
class MyFilterBackend(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
if 'pk' not in view.kwargs:
queryset = queryset.filter(...)
return queryset
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.