django 过滤器的执行

APIView 中,BaseDataPermissionFilter 是否执行,主要取决于你是否在视图中显式地配置了过滤器以及视图如何处理查询集。下面我将分别给出几个例子,展示不同情况下是否会执行 BaseDataPermissionFilter

1. 默认情况下,BaseDataPermissionFilter 会执行

如果在 APIView 中没有禁用任何过滤器,并且 DEFAULT_FILTER_BACKENDS 包含了 BaseDataPermissionFilter,则它会自动应用。

python 复制代码
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,它就不会执行。

python 复制代码
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,你可以显式调用它。

python 复制代码
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 方法中显式调用 BaseDataPermissionFilterfilter_queryset 方法来过滤数据。

4. BaseDataPermissionFilterModelViewSet 中的行为

如果你使用的是 ModelViewSet,并且 filter_backends 包含了 BaseDataPermissionFilter,它会自动应用。

python 复制代码
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. BaseDataPermissionFilterAPIView 中自定义过滤器

如果你已经在 APIView 中实现了自定义的过滤器,并且不希望 BaseDataPermissionFilter 执行,可以显式跳过。

python 复制代码
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 是否被执行,以及如何在自定义视图中处理数据权限过滤。

相关推荐
亿牛云爬虫专家1 小时前
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
分布式·python·架构·kubernetes·爬虫代理·监测·采集
ai小鬼头4 小时前
Ollama+OpenWeb最新版0.42+0.3.35一键安装教程,轻松搞定AI模型部署
后端·架构·github
萧曵 丶4 小时前
Rust 所有权系统:深入浅出指南
开发语言·后端·rust
老任与码5 小时前
Spring AI Alibaba(1)——基本使用
java·人工智能·后端·springaialibaba
蹦蹦跳跳真可爱5895 小时前
Python----OpenCV(图像増强——高通滤波(索贝尔算子、沙尔算子、拉普拉斯算子),图像浮雕与特效处理)
人工智能·python·opencv·计算机视觉
nananaij5 小时前
【Python进阶篇 面向对象程序设计(3) 继承】
开发语言·python·神经网络·pycharm
雷羿 LexChien5 小时前
从 Prompt 管理到人格稳定:探索 Cursor AI 编辑器如何赋能 Prompt 工程与人格风格设计(上)
人工智能·python·llm·编辑器·prompt
华子w9089258595 小时前
基于 SpringBoot+VueJS 的农产品研究报告管理系统设计与实现
vue.js·spring boot·后端
星辰离彬6 小时前
Java 与 MySQL 性能优化:Java应用中MySQL慢SQL诊断与优化实战
java·后端·sql·mysql·性能优化
敲键盘的小夜猫6 小时前
LLM复杂记忆存储-多会话隔离案例实战
人工智能·python·langchain