Django filter动态过滤与排序实现过程解析


Posted in Python onNovember 26, 2020

前期准备

在虚拟开发环境中安装:

pip install django-filter

在Django的项目配置文件中安装并配置django_filters应用:

INSTALLED_APPS = [
  ...
  'django_filters',
]

REST_FRAMEWORK = {
  # 过滤器默认后端
  'DEFAULT_FILTER_BACKENDS': (
      'django_filters.rest_framework.DjangoFilterBackend',),
}

快速使用

model.py

class User(models.Model):
  # 模型字段
  name = models.CharField(max_length=10, verbose_name="姓名")
  sex = models.BooleanField(default=1, verbose_name="性别")
  age = models.IntegerField(verbose_name="年龄")
  phone = models.CharField(max_length=20, null=True, verbose_name="电话")
  addr = models.CharField(max_length=100,null=True,verbose_name="地址")

  class Meta:
    db_table = "tb_user"
    verbose_name = "用户"
    verbose_name_plural = verbose_name

新建filter.py:过滤器类

import django_filters
from .models import User

class UserFilter(django_filters.FilterSet):

  class Meta:
    model = User
    fields = ["name", "age"] #指定动态过滤的字段,默认精准匹配

注意:

Meta字段说明
model: 引用的模型,不是字符串
fields:指明过滤字段,可以是列表,列表中字典可以过滤,默认是判等;也可以字典,字典可以自定义操作
exclude = ['password'] 排除字段,不允许使用列表中字典进行过滤

view.py

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.generics import ListAPIView
from rest_framework import filters
class UserViewSet(ListAPIView):
  queryset = User.objects.all()  #获取数据
  serializer_class = UserModelSerializer #指定序列化类
  filter_class = UserFilter  # 指定过滤器类

serializers.py

from rest_framework import serializers
from .models import User
class UserModelSerializer(serializers.ModelSerializer):
  class Meta:
    model = User
    fields = "__all__"

urls.py

path('user/',UserViewSet.as_view()),

首先理解上面是动态过滤,前端在请求头如下传递参数,传递参数的个数是不同的,而动态过滤只会过滤:有参数,且参数有值的项。

http://ip:port/user/?name=查找内容&age=查找内容
http://ip:port/user/?name=&age=查找内容
http://ip:port/user/?name=查找内容&age=
http://ip:port/user/?name=&age=
http://ip:port/user/

精准过滤、模糊过滤并存

class UserFilter(django_filters.FilterSet):
  class Meta:
    model = User
    # fields = ["name", "age"]
    fields = {
      "name": ['exact','icontains'],
      "age": ['exact'],
    }

exact:默认过滤方式,精确过滤

icontains:模糊过滤

http://ip:port/user/?name=查找内容&name_icontains=查找内容&age=查找内容

范围过滤

class UserFilter(django_filters.FilterSet):
  class Meta:
    model = User
    # fields = ["name", "age"]
    fields = {
      "name": ['exact','icontains'],
      "age": ['exact','gte','lte'],
    }

对以上filter来说

name 精确查找
name__icontains 模糊查找
age 精准查找
age__gte 大于等于
age__lte 小于等于

排序

class UserFilter(django_filters.FilterSet):
#定义排序字段:依赖哪个字段排序
  sort = django_filters.OrderingFilter(fields=('age',))
  class Meta:
    model = User
    # fields = ["name", "age"]
    fields = {
      "name": ['exact','icontains'],
      "age": ['exact','gte','lte'],
    }

url示例

http://ip:port/user/?name=查找内容&sort=age:表示升序
http://ip:port/user/?name=查找内容&sort=-age:表示降序

补充知识

这部分可以参考:https://zhuanlan.zhihu.com/p/110060840

过滤器可以自定义字段,开始我们这样定义过滤字段,以及每个字段是相等运算,模糊匹配,还是范围查询,但是这样的写法可能不太直观。

fields = {
"name": ['exact','icontains'],
"age": ['exact','gte','lte'],
}

我们可以做如下类型改变

class BookFilter(filters.FilterSet):
  btitle = filters.CharFilter(field_name='title',lookup_expr='icontains')
  pub_year = filters.CharFilter(field_name='bpub_date',lookup_expr='year')
  pub_year__gt = filters.CharFilter(field_name='bpub_date',lookup_expr='year__gt')
  bread__gt = filters.NumberFilter(field_name='bread',lookup_expr="gt")
  bread__lt = filters.NumberFilter(field_name='bread',lookup_expr="lt")

  class Meta:
    model = Bookinfo
    fields = ['title','bread','bcomment']

http://127.0.0.1:8000/book/?title=&bread=&bcomment=&btitle=%E5%B0%84%E9%9B%95&pub_year=&pub_year__gt=&bread__gt=&bread__lt=

过滤器每个字段内部配置:

field_name: 过滤字段名,为对应模型中字段名

lookup_expr: 查询时所要进行的操作,是等值,范围、模糊匹配等

过滤器字段类型:

CharFilter 字符串类型
BooleanFilter 布尔类型
DateTimeFilter 日期时间类型
DateFilter 日期类型
DateRangeFilter 日期范围
TimeFilter 时间类型
NumberFilter 数值类型,对应模型中IntegerField, FloatField, DecimalField

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python动态监控日志内容的示例
Feb 16 Python
python3访问sina首页中文的处理方法
Feb 24 Python
Python实现扫描指定目录下的子目录及文件的方法
Jul 16 Python
Python中几种操作字符串的方法的介绍
Apr 09 Python
Python数据结构之图的应用示例
May 11 Python
Python3多进程 multiprocessing 模块实例详解
Jun 11 Python
Pycharm+Scrapy安装并且初始化项目的方法
Jan 15 Python
详解python列表生成式和列表生成式器区别
Mar 27 Python
python:动态路由的Flask程序代码
Nov 22 Python
基于python的列表list和集合set操作
Nov 24 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
Jun 10 Python
Matplotlib 折线图plot()所有用法详解
Jul 28 Python
python中用ctypes模拟点击的实例讲解
Nov 26 #Python
python爬虫分布式获取数据的实例方法
Nov 26 #Python
python分布式爬虫中消息队列知识点详解
Nov 26 #Python
Flask-SocketIO服务端安装及使用代码示例
Nov 26 #Python
使用OpenCV校准鱼眼镜头的方法
Nov 26 #Python
最新PyCharm 2020.2.3永久激活码(亲测有效)
Nov 26 #Python
Django-celery-beat动态添加周期性任务实现过程解析
Nov 26 #Python
You might like
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
php 方便水印和缩略图的图形类
2009/05/21 PHP
利用Memcached在php下实现session机制 替换PHP的原生session支持
2010/08/21 PHP
完美解决:Apache启动问题―(OS 10022)提供了一个无效的参数
2013/06/08 PHP
PHP+Ajax实现的博客文章添加类别功能示例
2018/03/29 PHP
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
php gethostbyname获取域名ip地址函数详解
2010/01/24 Javascript
actionscript与javascript的区别
2011/05/25 Javascript
JavaScript版的TwoQueues缓存模型
2014/12/29 Javascript
js制作简易年历完整实例
2015/01/28 Javascript
jquery控制页面部分刷新的方法
2015/06/24 Javascript
深入了解JavaScript中的Symbol的使用方法
2015/07/28 Javascript
原生js实现百叶窗效果及原理介绍
2016/04/12 Javascript
新入门node.js必须要知道的概念(必看篇)
2016/08/10 Javascript
详解react-webpack2-热模块替换[HMR]
2017/08/03 Javascript
webpack组织模块打包Library的原理及实现
2018/03/10 Javascript
angular6.x中ngTemplateOutlet指令的使用示例
2018/08/09 Javascript
vue实现新闻展示页的步骤详解
2019/04/11 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
Python中常见的数据类型小结
2015/08/29 Python
python 环境变量和import模块导入方法(详解)
2017/07/11 Python
Python时间的精准正则匹配方法分析
2017/08/17 Python
EM算法的python实现的方法步骤
2018/01/02 Python
Python matplotlib画图与中文设置操作实例分析
2019/04/23 Python
PyTorch: 梯度下降及反向传播的实例详解
2019/08/20 Python
Pytorch Tensor 输出为txt和mat格式方式
2020/01/03 Python
实习单位推荐信范文
2013/11/27 职场文书
玩具公司的创业计划书
2013/12/31 职场文书
2014年医学生毕业自我鉴定
2014/03/26 职场文书
专项法律服务方案
2014/06/11 职场文书
2014大学生批评与自我批评思想汇报
2014/09/21 职场文书
教师个人师德总结
2015/02/06 职场文书
烈士陵园观后感
2015/06/08 职场文书
5分钟教你docker安装启动redis全教程(全新方式)
2021/05/29 Redis
Python连续赋值需要注意的一些问题
2021/06/03 Python
Feign调用传输文件异常的解决
2021/06/24 Java/Android