DRF——Filter条件搜索模块

文章目录

      • 条件搜索
        • 自定义Filter
        • 第三方Filter
        • 内置Filter

条件搜索

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

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

在drf中也有相应组件可以支持条件搜索。

自定义Filter

自定义filter后,需要在view视图类中定义filter_backeds类变量,django会自动读取循环filter_backeds中的filter类并执行实例化对象的filter_query方法。(get,put,delete,patch都会执行,post不会)

在这里插入图片描述

# urls.pyfrom django.urls import path
from app01 import viewsurlpatterns = [path('api/users/', views.UserView.as_view({"get": "list", "post": "create"})),path('api/users/<int:pk>/', views.UserView.as_view({"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"})),
]
# views.pyfrom rest_framework import serializers
from rest_framework.viewsets import ModelViewSet
from rest_framework.filters import BaseFilterBackend
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 Filter1(BaseFilterBackend):def filter_queryset(self, request, queryset, view):age = request.query_params.get('age')if not age:return querysetreturn queryset.filter(age=age)class Filter2(BaseFilterBackend):def filter_queryset(self, request, queryset, view):user_id = request.query_params.get('id')if not user_id:return querysetreturn queryset.filter(id__gt=user_id)class UserView(ModelViewSet):filter_backends = [Filter1, Filter2]queryset = models.UserInfo.objects.all()serializer_class = UserModelSerializerdef perform_create(self, serializer):""" 序列化:对请求的数据校验成功后,执行保存。"""serializer.save(depart_id=1, password="123")
第三方Filter

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

pip install django-filter

注册app:

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

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

最简单应用:

可以通过下载,django-filter组件,引入django_filter.rest_framework import DjangoFilterBancked。

在view视图类中定义filter_banckeds=[DjangoFilterBancked],和filterset_fields=[“id”,“name”,“age”]。

# 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):

还可以通过定义类变量filterset_class来定义更复杂的查询变量条件,

flilter类应该继承FilterSet,(类的构建类似于MoldeForm)

from rest_framework import serializers
from rest_framework.viewsets import ModelViewSet
from django_filters.rest_framework import DjangoFilterBackend
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):depart = filters.CharFilter(field_name="depart__title", lookup_expr="exact")min_id = filters.NumberFilter(field_name='id', lookup_expr='gte')class Meta:model = models.UserInfofields = ["min_id", "depart"]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")

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

  • 构建filter类的字段:

    NumberFilter,CharFilter,BooleanFilter,MultipleChoiceFilter,BaseInFilter,NumericRangeFilter,OrderingFilter,

    还可以通过CharFilter使用自定义搜索的方法。

  • 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'),
    
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',]
}
内置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):# ?search=DP%Tfilter_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 %DPT% ESCAPE '\' 
    OR 
    "app01_userinfo"."username" LIKE %DPT% ESCAPE '\' 
    OR 
    "app01_userinfo"."age" LIKE %DPT% ESCAPE '\'
    

若有错误与不足请指出,关注DPT一起进步吧!!!

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

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

相关文章

面试题详解

前言&#xff1a;这一期我们专门来巩固所学知识&#xff0c;同时见识一些面试题。对知识做出一个总结。 1 不创建临时变量交换两个整数 . 第一种方法 #include<stdio.h> int main() {int a 0;int b 0;scanf("%d %d", &a, &b);printf("交换前…

神经网络算法 - 一文搞懂BERT(基于Transformer的双向编码器)

本文将从BERT的本质、BERT的原理、BERT的应用三个方面&#xff0c;带您一文搞懂Bidirectional Encoder Representations from Transformers | BERT。 Google BERT BERT架构&#xff1a; 一种基于多层Transformer编码器的预训练语言模型&#xff0c;通过结合Tokenization、多种E…

Java基于数据库、乐观锁、悲观锁、Redis、Zookeeper分布式锁的简单案例实现(保姆级教程)

1. 分布式锁的定义 分布式锁是一种在分布式系统中用来协调多个进程或线程对共享资源进行访问的机制。它确保在分布式环境下&#xff0c;多个节点&#xff08;如不同的服务器或进程&#xff09;不会同时访问同一个共享资源&#xff0c;从而避免数据不一致、资源竞争等问题。 2…

等保测评服务的业务连续性规划:确保信息安全服务的韧性

在当前的数字化转型浪潮中&#xff0c;信息安全已成为企业运营的关键一环。等保测评服务作为信息安全合规的重要组成部分&#xff0c;其业务连续性规划对于保障服务的稳定性和客户信息资产的安全至关重要。本文将探讨等保测评服务的业务连续性规划策略&#xff0c;旨在构建一个…

树状数组算法

文章目录 树状数组是什么树状数组与线段树的区别与联系树状数组讲解点修&#xff0c;区查&#xff0c;讲解及模板点查&#xff0c;区修讲解及模板 树状数组是什么 树状数组是一种数据结构&#xff0c;提供O(logn)时间内的单点修改和区间求和操作&#xff0c;比线段树有更优的常…

MD编辑器学习笔记

MD编辑器学习笔记 目录标题文本样式列表图片链接代码片数学公式表格部分总结 目录 目录是使用“[TOC](目录&#xff09;”&#xff0c;记住别忘了加上&#xff08;&#xff09;标题 使用#来确定标题&#xff0c;几个#就是几级标题。记住#后面要加上空格文本样式 tips: 在写正…

物流抓取机器人整体设计方案

一、功能简介 1、运行环境&#xff1a;巡线行驶&#xff08;7路数字循迹&#xff0c;麦克纳姆轮车底盘&#xff09; 2、目标识别&#xff1a;颜色识别&#xff08;Maix-II Dock 视觉模块&#xff09; 3、目标定位&#xff1a;视觉测距&#xff08;Maix-II Dock 视觉模块&#x…

VS实⽤调试技巧(附调试例题)

&#x1f381;&#x1f381;创作不易&#xff0c;关注作者不迷路&#x1f380;&#x1f380; VS实⽤调试技巧&#xff08;附调试例题&#xff09; 前言一、什么是bug&#xff1f;二、什么是调试&#xff08;debug&#xff09;&#xff1f;三、Debug和Release四、VS调试快捷键五…

上书房信息咨询:商业项目调研方法有哪些

商业项目调研是为了了解市场需求、竞争情况和目标受众&#xff0c;从而制定合适的商业策略和项目规划。下面是一些常用的商业项目调研方法&#xff1a; 1、市场调查和问卷调查&#xff1a;通过设计和分发问卷&#xff0c;收集潜在顾客和目标市场的意见、偏好和需求。这可以帮助…

linux dig域名DNS 查询与iptables域名ip访问流量限制;PTR 反向解析从 IP 地址到域名的映射

一、域名 dns查询 在 Linux 系统中&#xff0c;你可以使用多种工具和技术来进行 DNS 查询和 IP 限制。以下是一些常用的方法和工具&#xff1a; DNS 查询 dig 命令&#xff1a; dig 是一个强大的命令行工具&#xff0c;用于查询 DNS 信息。 dig example.com你可以指定查询类型…

dockerfile搭建部署LNMP

目录 实验 架构&#xff1a; 实验步骤&#xff1a; nginx部分 mysql部分 php部分 实验 实验&#xff1a;用dockerfile搭建LNMP论坛 架构&#xff1a; 一台docker虚拟机 docker部署nginx 1.22 指定ip地址172.111.0.10 docker部署mysql 8.0.30 指定ip地址…

标准库标头 <execution> (C++17)学习

此头文件是算法库的一部分。本篇介绍策略类型的一些应用示例&#xff1a; 类 is_execution_policy (C17) 测试一个类是否表示某种执行策略 (类模板) 在命名空间 std::execution 定义 sequenced_policyparallel_policyparallel_unsequenced_policyunsequenced_policy (C17)(C1…

外排序之文件归并排序实现

外排序介绍 外排序是指能够处理极大量数据的排序算法。通常来说&#xff0c;外排序处理的数据不能一次装入内存&#xff0c;只能放在读写较慢的外存储器(通常是硬盘)上。外排序通常采用的是⼀种“排序-归并”的策略。在排序阶段&#xff0c;先读入能放在内存中的数据量&#x…

ACCESS 工具注入实战 凡诺靶场

简介 Access数据库注入攻击是一种常见的网络安全&#xff0c;通过注入SQL代码来获取未授权的数据访问权限。这种攻击利用了应用程序与数据库之间的交互漏洞&#xff0c;攻击者通过输入特定的SQL代码片段来操纵数据库查询&#xff0c;从而绕过应用程序的安全机制&#xff0c;获取…

基于x86 平台opencv的图像采集和seetaface6的人脸特征点功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.2 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的人脸特征点功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的人脸特征点模块从而…

Selenium + Python 自动化测试19(补充-读取各种文件数据操作)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了数据驱动测试中如何完成重复的测试实例&#xff0c;今天我们补充一些读取各种文件的方法。 本篇文章我们讨论一下如何使用读取txt、CSV、Excel文件&#xff0…

多门店多端平台系统小程序源码

&#x1f525;【健身新纪元】多门店多端分开健身系统&#xff0c;打造你的个性化健身体验&#x1f31f; &#x1f3cb;️‍♀️ 一、告别单一&#xff0c;拥抱多元化健身时代 你还在为找不到合适的健身房而烦恼吗&#xff1f;或是想要随时随地开启健身模式&#xff0c;却受限…

xss靶场 pwnfunction WW3

目录 代码 代码分析 payload构造 结果 代码 <div><h4>Meme Code</h4><textarea class"form-control" id"meme-code" rows"4"></textarea><div id"notify"></div> </div><scri…

ubuntu上cmake3.30.2的安装

引言 安装下载安装包将安装包从windows拷贝到ubuntu解压进入解压后的文件夹执行boostrap编译CMake安装CMake查看是否安装成功 目前的ubuntu系统是20.04.4&#xff0c;用命令行安装了cmake的版本是3.16的&#xff0c;由于项目需要升级cmake到cmake3.22之上&#xff0c;使用命令行…

如何使用cornerstone3D渲染3D影像

&#x1f353; 前言 在日常开发中经常会遇到除了渲染MPR视图外&#xff0c;还需要渲染3D扫描影像&#xff0c;本文从具体的实现、viewport type解读、场景预设等方面来介绍3D具体的实现及涉及到的相关概念。 &#x1f951; 效果演示 点击查看完整代码 &#x1f352; 实现及概…