django 过滤器的执行
在 APIView
中,BaseDataPermissionFilter
是否执行,主要取决于你是否在视图中显式地配置了过滤器以及视图如何处理查询集。下面我将分别给出几个例子,展示不同情况下是否会执行 BaseDataPermissionFilter
。
1. 默认情况下,BaseDataPermissionFilter
会执行
如果在 APIView
中没有禁用任何过滤器,并且 DEFAULT_FILTER_BACKENDS
包含了 BaseDataPermissionFilter
,则它会自动应用。
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from myapp.models import MyModel
from myapp.filters import BaseDataPermissionFilter
from rest_framework import status
class MyModelAPIView(APIView):
permission_classes = [IsAuthenticated] # 需要认证
def get(self, request, *args, **kwargs):
# 默认执行过滤器
queryset = MyModel.objects.all() # 获取查询集
# 过滤器会自动执行
filtered_queryset = BaseDataPermissionFilter().filter_queryset(request, queryset, self)
data = [{"id": item.id, "name": item.name} for item in filtered_queryset]
return Response(data, status=status.HTTP_200_OK)
在这个例子中,BaseDataPermissionFilter
会自动执行,因为没有禁用它。filter_queryset
方法会根据用户权限过滤查询集。
2. 禁用过滤器,BaseDataPermissionFilter
不会执行
如果你在视图中禁用了 BaseDataPermissionFilter
,它就不会执行。
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from myapp.models import MyModel
from rest_framework import status
class MyModelAPIView(APIView):
permission_classes = [IsAuthenticated]
filter_backends = [] # 禁用所有过滤器,包括 BaseDataPermissionFilter
def get(self, request, *args, **kwargs):
queryset = MyModel.objects.all()
# 这里手动过滤,BaseDataPermissionFilter 不会被应用
filtered_queryset = self.custom_filter(queryset, request.user)
data = [{"id": item.id, "name": item.name} for item in filtered_queryset]
return Response(data, status=status.HTTP_200_OK)
def custom_filter(self, queryset, user):
# 自定义过滤逻辑
return queryset.filter(dept_belong=user.dept)
在这个例子中,通过将 filter_backends
设置为空列表,禁用了所有过滤器,因此 BaseDataPermissionFilter
不会执行。你可以在视图内手动编写过滤逻辑,如 custom_filter
。
3. 视图内手动调用 BaseDataPermissionFilter
如果你希望在 APIView
中手动应用 BaseDataPermissionFilter
,你可以显式调用它。
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from myapp.models import MyModel
from myapp.filters import BaseDataPermissionFilter
from rest_framework import status
class MyModelAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, *args, **kwargs):
queryset = MyModel.objects.all()
# 手动调用 BaseDataPermissionFilter 进行数据过滤
filtered_queryset = BaseDataPermissionFilter().filter_queryset(request, queryset, self)
data = [{"id": item.id, "name": item.name} for item in filtered_queryset]
return Response(data, status=status.HTTP_200_OK)
在这个例子中,即使 BaseDataPermissionFilter
是全局过滤器,它仍然会手动应用。在 get
方法中显式调用 BaseDataPermissionFilter
的 filter_queryset
方法来过滤数据。
4. BaseDataPermissionFilter
在 ModelViewSet
中的行为
如果你使用的是 ModelViewSet
,并且 filter_backends
包含了 BaseDataPermissionFilter
,它会自动应用。
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from myapp.models import MyModel
from myapp.filters import BaseDataPermissionFilter
from myapp.serializers import MyModelSerializer
class MyModelViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
filter_backends = [BaseDataPermissionFilter] # 添加过滤器
在这个例子中,BaseDataPermissionFilter
会被自动应用,因为它被添加到了 filter_backends
中。ModelViewSet
会自动调用 filter_queryset
,所以每次查询都会经过该过滤器进行数据权限的校验。
5. BaseDataPermissionFilter
在 APIView
中自定义过滤器
如果你已经在 APIView
中实现了自定义的过滤器,并且不希望 BaseDataPermissionFilter
执行,可以显式跳过。
from rest_framework.views import APIView
from rest_framework.response import Response
from myapp.models import MyModel
from myapp.filters import BaseDataPermissionFilter
from rest_framework import status
class MyModelAPIView(APIView):
permission_classes = [IsAuthenticated]
filter_backends = [] # 禁用所有过滤器,包括 BaseDataPermissionFilter
def get(self, request, *args, **kwargs):
queryset = MyModel.objects.all()
# 自定义过滤逻辑,避免 BaseDataPermissionFilter 执行
filtered_queryset = self.custom_filter(queryset, request.user)
data = [{"id": item.id, "name": item.name} for item in filtered_queryset]
return Response(data, status=status.HTTP_200_OK)
def custom_filter(self, queryset, user):
# 自定义的过滤逻辑,不经过 BaseDataPermissionFilter
return queryset.filter(dept_belong=user.dept)
在这个例子中,BaseDataPermissionFilter
被禁用了,取而代之的是手动实现的 custom_filter
方法。
总结
- 默认情况下,
BaseDataPermissionFilter
会执行,特别是如果在filter_backends
中配置了它,或者没有禁用它。 - 禁用过滤器:可以通过在
APIView
中设置filter_backends = []
来禁用过滤器,避免执行BaseDataPermissionFilter
。 - 手动调用过滤器:如果需要,你可以在视图中手动调用
BaseDataPermissionFilter
来过滤查询集。 - 自定义过滤器:如果在视图中自定义了过滤逻辑,而不希望执行
BaseDataPermissionFilter
,可以禁用全局过滤器,或者在视图内实现自己的过滤方法。
通过以上方式,你可以灵活控制 BaseDataPermissionFilter
是否被执行,以及如何在自定义视图中处理数据权限过滤。