Django-filter

准备工作

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

python 复制代码
pip install django-filter

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

python 复制代码
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文件在应用目录中:

python 复制代码
import django_filters
from .models import Task


class TaskFilter(django_filters.FilterSet):

    class Meta:
        model = Task
        fields = ['template_id', 'project_id']

注意如果过滤的字段本身就属于Task模型的字段,那么不用额外定义,如果过滤的条件字段不属于Task模型的字段,那么需要额外定义如下:

同时,如果想要定义精准过滤和模糊过滤,可以定义如下:

python 复制代码
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

python 复制代码
class TaskViewSet(ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    lookup_field = "task_id"
    filter_class = TaskFilter

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

python 复制代码
    @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

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

python 复制代码
tasks = self.filter_queryset(self.get_queryset())

路径匹配

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

总结

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

相关推荐
若水不如远方几秒前
分布式一致性(三):共识的黎明——Quorum 机制与 Basic Paxos
分布式·后端·算法
三千星1 分钟前
从Java到AI:我的转型之路 Ⅱ —— 手撸一个DeepSeek工具库
后端
喵手2 分钟前
Python爬虫实战:城市停车收费标准自动化采集系统 - 让停车费透明化的技术实践(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·城市停车收费标准·采集城市停车收费数据·采集停车数据csv文件导出
beata3 分钟前
Java基础-9:深入 Java 虚拟机(JVM):从底层源码到核心原理的全面解析
java·后端
无水先生3 分钟前
python函数的参数管理(01)*args和**kwargs
开发语言·python
py小王子4 分钟前
dy评论数据爬取实战:基于DrissionPage的自动化采集方案
大数据·开发语言·python·毕业设计
Pyeako6 分钟前
opencv计算机视觉--LBPH&EigenFace&FisherFace人脸识别
人工智能·python·opencv·计算机视觉·lbph·eigenface·fisherface
小陶的学习笔记10 分钟前
python~基础
开发语言·python·学习
多恩Stone10 分钟前
【3D AICG 系列-9】Trellis2 推理流程图超详细介绍
人工智能·python·算法·3d·aigc·流程图
ID_1800790547312 分钟前
Python结合淘宝关键词API进行商品价格监控与预警
服务器·数据库·python