• Django-filter


    准备工作

    首先,确保你已经安装了django-filter包。如果没有,请使用以下命令安装:

    pip install django-filter
    

    然后,在你的settings.py文件中添加django_filters到INSTALLED_APPS列表中:

    INSTALLED_APPS = [
        # ...
        'django_filters',
    ]
    

    本机环境:

    Django==3.2.15

    django-filter==24.2

    ps:安装的包是django-filter,但是在settings里面设置的却是django-filters。这也是蛮坑的一个点。

    目的

    一个TaskViewSet,带模型Task的,里面有两个自定义动作,一个是根据template_id过滤,一个是根据project_id过滤

    filters.py:

    那么我可以创建一个filters.py文件在应用目录中:

    import django_filters
    from .models import Task
    
    
    class TaskFilter(django_filters.FilterSet):
    
        class Meta:
            model = Task
            fields = ['template_id', 'project_id']
    
    

    注意如果过滤的字段本身就属于Task模型的字段,那么不用额外定义,如果过滤的条件字段不属于Task模型的字段,那么需要额外定义如下:
    同时,如果想要定义精准过滤和模糊过滤,可以定义如下:

    from django.db.models import Q
    
    from .models import BkHost
    
    
    class BkHostFilter(django_filters.FilterSet):
        operator = django_filters.CharFilter(field_name='operator', method='filter_operator')
    
        class Meta:
            model = BkHost
            fields = {
                'host_id': ['exact'],
                'host_name': ['exact', 'icontains'],
                'host_innerip': ['exact', 'contains'],
            }
    
        def filter_operator(self, queryset, name, value):
            return queryset.filter(Q(operator__exact=value) | Q(operator__icontains=value))
    

    其中icontains表示不区分大小写的模糊匹配。contains表示区分大小写的模糊匹配。

    视图集

    首先视图集本身要指定filter_class

    class TaskViewSet(ModelViewSet):
        queryset = Task.objects.all()
        serializer_class = TaskSerializer
        lookup_field = "task_id"
        filter_class = TaskFilter
    

    如果是自定义动作(即被@action装饰器修饰的)需要应用django-filter的话,需要在动作中再次手动指定

        @swagger_auto_schema(manual_parameters=[openapi.Parameter(
            'template_id',
            openapi.IN_QUERY,
            type=openapi.TYPE_INTEGER,
        )])
        @action(detail=False, methods=["get"], url_path="list-by-template")
        def list_by_template(self, request):  
      		# ……省略代码
      		# 手动应用过滤器
            filterset = self.filter_class(request.GET, queryset=self.get_queryset())
            if not filterset.is_valid():
                return Response(filterset.errors, status=400)
            tasks = filterset.qs
    

    如果是非自定义动作,可以直接如下使用:

    tasks = self.filter_queryset(self.get_queryset())
    

    路径匹配

    注意django-filter会从路径参数中拿在filters.py中指定的字段。所以如上代码只接受路径:
    http://{your-domain}:8000/tasks/list-by-template/?template_id=xxx

    总结

    如果是自定义动作,除非过滤条件比较复杂,不然不需要用django-filter,因为还要手动指定,比较复杂。

  • 相关阅读:
    滚雪球学Java(44):掌握Java编程的关键:深入解析System类
    C++之va_start、vasprintf、va_end应用总结(二百二十六)
    【JavaEE】多线程(五)- 基础知识完结篇
    C语言| 求1到100之间奇数的平均值.
    行为型模式-责任链模式
    Linux编程:定时器setitimer
    shamir 秘密共享
    分布式事务处理:挑战与解决方案
    MyBatis的动态 SQL、代理机制与多级缓存
    JavaScript 回调函数/Promise/ async/await
  • 原文地址:https://blog.csdn.net/zhiaidaidai/article/details/139637851