DRF的filter组件

 DRF的Filter组件

如果某个API需要传递一些条件进行搜索,其实就在是URL后面通过GET传参即可,例如:

/api/users?age=19&category=12

在drf中filter组件可以支持条件搜索。

1. 自定义filter

# models.py
from django.db import modelsclass Role(models.Model):""" 角色表 """title = models.CharField(verbose_name='名称', max_length=32)class Department(models.Model):""" 部门表 """title = models.CharField(verbose_name='名称', max_length=32)class UserInfo(models.Model):username = models.CharField(verbose_name='用户名', max_length=32)age = models.CharField(verbose_name='年龄', max_length=32)level_choice = ((1, 'VIP'), (2, 'SVIP'), (3, 'PARTNER'))level = models.SmallIntegerField(verbose_name='级别', choices=level_choice)email = models.CharField(verbose_name='邮箱', max_length=32)# 创建外键depart = models.ForeignKey(verbose_name="部门", to="Department", on_delete=models.CASCADE)# 多对多roles = models.ManyToManyField(verbose_name="角色", to="Role")
# views.py
from rest_framework import serializers
from rest_framework.filters import BaseFilterBackend
from rest_framework.viewsets import ModelViewSetfrom api import models# Create your views here.
class UserSerializer(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display", read_only=True)extra = serializers.SerializerMethodField(read_only=True)class Meta:model = models.UserInfofields = ['username', 'age', 'email', "level_text", 'extra']def get_extra(self, obj):return '我是多余的'# 自定义Filter
class Filter1(BaseFilterBackend):def filter_queryset(self, request, queryset, view):age = request.GET.get('age')  # 可以使用request.query_paramsif not age:return querysetreturn queryset.filter(age=age)class Filter2(BaseFilterBackend):def filter_queryset(self, request, queryset, view):id = request.query_params.get('id')if not id:return querysetreturn queryset.filter(id=id)class UserView(ModelViewSet):filter_backends = [Filter1, Filter2]  # 加入需要传递的Filterqueryset = models.UserInfo.objects.all()  # GenericAPIView这个类提供的变量serializer_class = UserSerializer

返回值:

源码流程

2. 第三方filter(常用)

在drf开发中有一个常用的第三方过滤器:DjangoFilterBackend。

pip install django-filter

注册app:

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

示例1: 简单

视图配置和应用:

# views.py
from rest_framework import serializers
from rest_framework.viewsets import ModelViewSet
from django_filters.rest_framework import DjangoFilterBackend
from app01 import modelsclass UserModelSerializer(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display",read_only=True)extra = serializers.SerializerMethodField(read_only=True)class Meta:model = models.UserInfofields = ["username", "age", "email", "level_text", "extra"]def get_extra(self, obj):return 666class UserView(ModelViewSet):filter_backends = [DjangoFilterBackend, ]filterset_fields = ["id", "age", "email"]queryset = models.UserInfo.objects.all()serializer_class = UserModelSerializerdef perform_create(self, serializer):""" 序列化:对请求的数据校验成功后,执行保存。"""serializer.save(depart_id=1, password="123")

示例2: 复杂

视图配置和应用(示例3):

from rest_framework import serializers
from rest_framework.viewsets import ModelViewSet
from django_filters.rest_framework import DjangoFilterBackend, OrderingFilter
from django_filters import FilterSet, filters
from app01 import modelsclass UserModelSerializer(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display",read_only=True)depart_title = serializers.CharField(source="depart.title",read_only=True)extra = serializers.SerializerMethodField(read_only=True)class Meta:model = models.UserInfofields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"]def get_extra(self, obj):return 666class MyFilterSet(FilterSet):# /api/users/?min_id=2  -> id>=2min_id = filters.NumberFilter(field_name='id', lookup_expr='gte')# /api/users/?name=wupeiqi  -> not ( username=wupeiqi )name = filters.CharFilter(field_name="username", lookup_expr="exact", exclude=True)# /api/users/?depart=xx     -> depart__title like %xx%depart = filters.CharFilter(field_name="depart__title", lookup_expr="contains")# /api/users/?token=true      -> "token" IS NULL# /api/users/?token=false     -> "token" IS NOT NULLtoken = filters.BooleanFilter(field_name="token", lookup_expr="isnull")# /api/users/?email=xx     -> email like xx%email = filters.CharFilter(field_name="email", lookup_expr="startswith")# /api/users/?level=2&level=1   -> "level" = 1 OR "level" = 2(必须的是存在的数据,否则报错-->内部有校验机制)# level = filters.AllValuesMultipleFilter(field_name="level", lookup_expr="exact")level = filters.MultipleChoiceFilter(field_name="level", lookup_expr="exact", choices=models.UserInfo.level_choices)# /api/users/?age=18,20     -> age in [18,20]age = filters.BaseInFilter(field_name='age', lookup_expr="in")# /api/users/?range_id_max=10&range_id_min=1    -> id BETWEEN 1 AND 10range_id = filters.NumericRangeFilter(field_name='id', lookup_expr='range')# /api/users/?ordering=id     -> order by id asc# /api/users/?ordering=-id     -> order by id desc# /api/users/?ordering=age     -> order by age asc# /api/users/?ordering=-age     -> order by age descordering = filters.OrderingFilter(fields=["id", "age"])# /api/users/?size=1     -> limit 1(自定义搜索)size = filters.CharFilter(method='filter_size', distinct=False, required=False)class Meta:model = models.UserInfofields = ["id", "min_id", "name", "depart", "email", "level", "age", 'range_id', "size", "ordering"]def filter_size(self, queryset, name, value):int_value = int(value)return queryset[0:int_value]class UserView(ModelViewSet):filter_backends = [DjangoFilterBackend, ]filterset_class = MyFilterSetqueryset = models.UserInfo.objects.all()serializer_class = UserModelSerializerdef perform_create(self, serializer):""" 序列化:对请求的数据校验成功后,执行保存。"""serializer.save(depart_id=1, password="123")

补充

lookup_expr有很多常见选择:

'exact': _(''),
'iexact': _(''),'contains': _('contains'),
'icontains': _('contains'),
'startswith': _('starts with'),
'istartswith': _('starts with'),
'endswith': _('ends with'),  
'iendswith': _('ends with'),'gt': _('is greater than'),
'gte': _('is greater than or equal to'),
'lt': _('is less than'),
'lte': _('is less than or equal to'),'in': _('is in'),
'range': _('is in range'),
'isnull': _(''),'regex': _('matches regex'),
'iregex': _('matches regex'),

全局配置和应用:

# settings.py 全局配置REST_FRAMEWORK = {'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend',]
}

3. 内置filter

drf源码中内置了2个filter,分别是:

  • OrderingFilter,支持排序。

    from rest_framework import serializers
    from rest_framework.viewsets import ModelViewSet
    from app01 import models
    from rest_framework.filters import OrderingFilterclass UserModelSerializer(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display",read_only=True)depart_title = serializers.CharField(source="depart.title",read_only=True)extra = serializers.SerializerMethodField(read_only=True)class Meta:model = models.UserInfofields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"]def get_extra(self, obj):return 666class UserView(ModelViewSet):filter_backends = [OrderingFilter, ]# ?order=id# ?order=-id# ?order=ageordering_fields = ["id", "age"]queryset = models.UserInfo.objects.all()serializer_class = UserModelSerializerdef perform_create(self, serializer):""" 序列化:对请求的数据校验成功后,执行保存。"""serializer.save(depart_id=1, password="123")
    
  • SearchFilter,支持模糊搜索。

    from rest_framework import serializers
    from rest_framework.viewsets import ModelViewSet
    from app01 import models
    from rest_framework.filters import SearchFilterclass UserModelSerializer(serializers.ModelSerializer):level_text = serializers.CharField(source="get_level_display",read_only=True)depart_title = serializers.CharField(source="depart.title",read_only=True)extra = serializers.SerializerMethodField(read_only=True)class Meta:model = models.UserInfofields = ["id", "username", "age", "email", "level_text", "extra", "depart_title"]def get_extra(self, obj):return 666class UserView(ModelViewSet):filter_backends = [SearchFilter, ]search_fields = ["id", "username", "age"]queryset = models.UserInfo.objects.all()serializer_class = UserModelSerializerdef perform_create(self, serializer):""" 序列化:对请求的数据校验成功后,执行保存。"""serializer.save(depart_id=1, password="123")
    "app01_userinfo"."id" LIKE %18% ESCAPE '\' 
    OR 
    "app01_userinfo"."username" LIKE %18% ESCAPE '\' 
    OR 
    "app01_userinfo"."age" LIKE %18% ESCAPE '\'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/92225.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[NLP]LLM 训练时GPU显存耗用量估计

以LLM中最常见的Adam fp16混合精度训练为例,分析其显存占用有以下四个部分: GPT-2含有1.5B个参数,如果用fp16格式,只需要1.5G*2Byte3GB显存, 但是模型状态实际上需要耗费1.5B*1624GB. 比如说有一个模型参数量是1M,在…

[GAN] 使用GAN网络进行图片生成的“调参人”入门指南——生成向日葵图片

[GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片 文章目录 [GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片1. 写在前面:1.1 应用场景:1.2 数据集情况:1.3 实验原理讲解和分析(简化版&#x…

Flink CDC系列之:TiDB CDC 导入 Elasticsearch

Flink CDC系列之:TiDB CDC 导入 Elasticsearch 一、通过docker 来启动 TiDB 集群二、下载 Flink 和所需要的依赖包三、在TiDB数据库中创建表和准备数据四、启动Flink 集群,再启动 SQL CLI五、在 Flink SQL CLI 中使用 Flink DDL 创建表六、Kibana查看Ela…

H3C QoS打标签和限速配置案例

EF:快速转发 AF:确保转发 CS:给各种协议用的 BE:默认标记(尽力而为) VSR-88-2 出口路由配置: [H3C]dis current-configuration version 7.1.075, ESS 8305 vlan 1 traffic classifier vlan10 operator and if-match a…

关于consul的下载方法

linux下 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo sudo yum -y install consulwindow下 https://developer.hashicorp.com/consul/downloads 然后把里面的exe文件放在gopath下就行了 验证…

苍穹外卖day11笔记

今日首先介绍前端技术Apache ECharts,说明后端需要准备的数据,然后讲解具体统计功能的实现,包括营业额统计、用户统计、订单统计、销量排名。 一、ECharts 是什么 ECharts是一款基于 Javascript 的数据可视化图表库。我们用它来展示图表数…

说一下什么是tcp的2MSL,为什么客户端在 TIME-WAIT 状态必须等待 2MSL 的时间?

1.TCP之2MSL 1.1 MSL MSL:Maximum Segment Lifetime报文段最大生存时间,它是任何报文段被丢弃前在网络内的最长时间 1.2为什么存在MSL TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段,并且TTL的限制是基于跳数 1.3…

ceph相关概念和部署

Ceph 可用于向云提供 Ceph 对象存储 平台和 Ceph 可用于提供 Ceph 块设备服务 到云平台。Ceph 可用于部署 Ceph 文件 系统。所有 Ceph 存储集群部署都从设置 每个 Ceph 节点,然后设置网络。 Ceph 存储集群需要满足以下条件:至少一个 Ceph 监控器&#x…

继承和多态C++

这里写目录标题 继承public、protected、private 修饰类的成员public、protected、private 指定继承方式改变访问权限 C继承时的名字遮蔽问题基类成员函数和派生类成员函数不构成重载C基类和派生类的构造函数构造函数的调用顺序基类构造函数调用规则 C基类和派生类的析构函数C多…

Android app专项测试之耗电量测试

前言 耗电量指标 待机时间成关注目标 提升用户体验 通过不同的测试场景,找出app高耗电的场景并解决 01、需要的环境准备 1、python2.7(必须是2.7,3.X版本是不支持的) 2、golang语言的开发环境 3、Android SDK 此三个的环境搭建这里就不详细说了&am…

无涯教程-Perl - send函数

描述 此函数在SOCKET上发送消息(与recv相反)。如果Socket未连接,则必须提供一个目标以与TO参数进行通信。在这种情况下,将使用sendto系统功能代替系统发送功能。 FLAGS参数由按位或0以及MSG_OOB和MSG_DONTROUTEoptions中的一个或多个形成。 MSG_OOB允许您在支持此概念的Socke…

炬芯科技发布全新第二代智能手表芯片,引领腕上新趋势!

2023年7月,炬芯科技宣布全新第二代智能手表芯片正式发布。自2021年底炬芯科技推出第一代的智能手表芯片开始便快速获得了市场广泛认可和品牌客户的普遍好评。随着技术的不断创新和突破,为了更加精准地满足市场多元化的变幻和用户日益增长的体验需求&…

C语言入门 Day_5 四则运算

目录 前言 1.四则运算 2.其他运算 3.易错点 4.思维导图 前言 图为世界上第一台通用计算机ENIAC,于1946年2月14日在美国宾夕法尼亚大学诞生。发明人是美国人莫克利(JohnW.Mauchly)和艾克特(J.PresperEckert)。 计算机的最开始…

轻量级 Spring Task 任务调度可视化管理

Spring Task/Spring Scheduler 傻傻分不清 首先做一下“名词解释”,分清楚这两者的区别: Spring Task Spring Task 是 Spring 框架自带的一个任务调度模块,提供了基本的任务调度功能。它是通过 Java 的 Timer 和 TimerTask 类来实现的&…

ReactDOM模块react-dom/client没有默认导出报错解决办法

import ReactDOM 模块“"E:/Dpandata/Shbank/rt-pro/node_modules/.pnpm/registry.npmmirror.comtypesreact-dom18.2.7/node_modules/types/react-dom/client"”没有默认导出。 解决办法 只需要在tsconfig.json里面添加配置 "esModuleInterop": true 即…

数据结构介绍

1、什么是数据结构呢? 计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。数据结构是为了更方便的管理和使用数据,需要结合具体的业务来进行选择。一般情况下,精心选择的数据结构可以带来更高的运行或者存储效率。…

6.利用matlab完成 符号矩阵的秩和 符号方阵的逆矩阵和行列式 (matlab程序)

1.简述 利用M文件建立矩阵 对于比较大且比较复杂的矩阵,可以为它专门建立一个M文件。下面通过一个简单例子来说明如何利用M文件创建矩阵。 例2-2 利用M文件建立MYMAT矩阵。(1) 启动有关编辑程序或MATLAB文本编辑器,并输入待建矩阵:(2) 把…

【2023年11月第四版教材】《第5章-信息系统工程之软件工程(第一部分)》

《第5章-信息系统工程(第一部分)》 章节说明1 软件工程1.1 架构设计1.2 需求分析 章节说明 65%为新增内容, 预计选择题考5分,案例和论文不考;本章与第三版教材一样的内容以楷体字进行标注! 1 软件工程 1.1 架构设计 1、软件架…

Linux文件权限一共10位长度,分成四段

Linux文件权限一共10位长度,分成四段 Linux文件权限 1、 文件aaa的访问权限为rw-r--r--,现要增加所有用户的执行权限和同组用户的写权限,下列哪些命令是正确的? a) chmod ax gw aaa √ b) chmod 764 aaa c) chmod 775 aaa √ d)…

vue3+vite+pinia

目录 一、项目准备 1.1、Vite搭建项目 1.2、vue_cli创建项目 二、组合式API(基于setup) 2.1、ref 2.2、reactive 2.3、toRefs 2.4、watch和watchEffect 2.5、computed 2.6、生命周期钩子函数 2.7、setup(子组件)的第一个参数-props 2.8、setup(子组件)的第二个参数…