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脚本实现统计日志文件中的ip访问次数代码分享
Aug 06 Python
Python爬取网易云音乐热门评论
Mar 31 Python
Python编写一个闹钟功能
Jul 11 Python
python Matplotlib画图之调整字体大小的示例
Nov 20 Python
Python读csv文件去掉一列后再写入新的文件实例
Dec 28 Python
python3+pyqt5+itchat微信定时发送消息的方法
Feb 20 Python
Python django框架应用中实现获取访问者ip地址示例
May 17 Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 Python
Python3直接爬取图片URL并保存示例
Dec 18 Python
matplotlib基础绘图命令之bar的使用方法
Aug 13 Python
python Gabor滤波器讲解
Oct 26 Python
python3 使用ssh隧道连接mysql的操作
Dec 05 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
PHP之变量、常量学习笔记
2008/03/27 PHP
PHP使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
PHP实现的一致性哈希算法完整实例
2015/11/14 PHP
laravel5.1框架model类查询的实现方法
2019/10/08 PHP
PHP用swoole+websocket和redis实现web一对一聊天
2019/11/05 PHP
日期处理的js库(迷你版)--自建js库总结
2011/11/21 Javascript
jQuery 获取URL的GET参数值的小例子
2013/04/18 Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
2014/03/28 Javascript
JavaScript中使用document.write向页面输出内容实例
2014/10/16 Javascript
Javascript前端UI框架Kit使用指南之kitjs的对话框组件
2014/11/28 Javascript
JS实现从网页顶部掉下弹出层效果的方法
2015/08/06 Javascript
解析Node.js基于模块和包的代码部署方式
2016/02/16 Javascript
Javascript中indexOf()和lastIndexOf应用方法实例
2016/08/24 Javascript
原生JS获取元素集合的子元素宽度实例
2016/12/14 Javascript
微信小程序 用户数据解密详细介绍
2017/01/09 Javascript
ES6 Proxy实现Vue的变化检测问题
2019/06/11 Javascript
vue路由守卫及路由守卫无限循环问题详析
2019/09/05 Javascript
layui 数据表格+分页+搜索+checkbox+缓存选中项数据的方法
2019/09/21 Javascript
详解vue中$nextTick和$forceUpdate的用法
2019/12/11 Javascript
编写Python脚本来获取mp3文件tag信息的教程
2015/05/04 Python
Python实现程序的单一实例用法分析
2015/06/03 Python
pandas数据筛选和csv操作的实现方法
2019/07/02 Python
利用Python实现Shp格式向GeoJSON的转换方法
2019/07/09 Python
PyCharm 无法 import pandas 程序卡住的解决方式
2020/03/09 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
2020/05/18 Python
python rolling regression. 使用 Python 实现滚动回归操作
2020/06/08 Python
CSS3中的5个有趣的新技术
2009/04/02 HTML / CSS
html5中地理位置定位api接口开发应用小结
2013/01/04 HTML / CSS
澳大利亚著名的纺织品品牌:Canningvale
2020/05/05 全球购物
七年级音乐教学反思
2014/01/26 职场文书
2014年教务工作总结
2014/12/03 职场文书
催款函范文
2015/06/24 职场文书
广播体操比赛主持词
2015/06/29 职场文书
python中如何对多变量连续赋值
2021/06/03 Python
基于Redis结合SpringBoot的秒杀案例详解
2021/10/05 Redis
Python+Matplotlib图像上指定坐标的位置添加文本标签与注释
2022/04/11 Python