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各大聊天系统的屏蔽脏话功能原理
Dec 01 Python
python3.5 + PyQt5 +Eric6 实现的一个计算器代码
Mar 11 Python
Python实现简单的获取图片爬虫功能示例
Jul 12 Python
python实现图片批量压缩程序
Jul 23 Python
Python面向对象程序设计构造函数和析构函数用法分析
Apr 12 Python
Django实现发送邮件功能
Jul 18 Python
python爬虫 爬取超清壁纸代码实例
Aug 16 Python
Django1.11自带分页器paginator的使用方法
Oct 31 Python
python3连接MySQL8.0的两种方式
Feb 17 Python
Python中logging日志库实例详解
Feb 19 Python
Python操作dict时避免出现KeyError的几种解决方法
Sep 20 Python
python中delattr删除对象方法的代码分析
Dec 15 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 fgetcsv 定义和用法(附windows与linux下兼容问题)
2012/05/29 PHP
PHP获取数组中某元素的位置及array_keys函数应用
2013/01/29 PHP
PHP之生成GIF动画的实现方法
2013/06/07 PHP
PHP输出缓冲控制Output Control系列函数详解
2015/07/02 PHP
php微信公众平台交互与接口详解
2016/11/28 PHP
PHP后台备份MySQL数据库的源码实例
2019/03/18 PHP
清除网页历史记录,屏蔽后退按钮!
2008/12/22 Javascript
Jquery操作下拉框(DropDownList)实现取值赋值
2013/08/13 Javascript
不同Jquery版本引发的问题解决
2013/10/14 Javascript
js 递归和定时器的实例解析
2017/02/03 Javascript
jQuery封装placeholder效果实现方法,让低版本浏览器支持该效果
2017/07/08 jQuery
解析vue中的$mount
2017/12/21 Javascript
vue实现Excel文件的上传与下载功能的两种方式
2019/06/28 Javascript
VUE的history模式下除了index外其他路由404报错解决办法
2019/08/21 Javascript
layui点击按钮页面会自动刷新的解决方案
2019/10/25 Javascript
Vue 实现对quill-editor组件中的工具栏添加title
2020/08/03 Javascript
Vue和React有哪些区别
2020/09/12 Javascript
vue-openlayers实现地图坐标弹框效果
2020/09/24 Javascript
python基于Tkinter库实现简单文本编辑器实例
2015/05/05 Python
Python for Informatics 第11章 正则表达式(一)
2016/04/21 Python
简单掌握Python的Collections模块中counter结构的用法
2016/07/07 Python
Python编程实现双链表,栈,队列及二叉树的方法示例
2017/11/01 Python
Django 重写用户模型的实现
2019/07/29 Python
python打包成so文件过程解析
2019/09/28 Python
Django 自动生成api接口文档教程
2019/11/19 Python
Selenium使用Chrome模拟手机浏览器方法解析
2020/04/10 Python
python基于exchange函数发送邮件过程详解
2020/11/06 Python
python爬虫智能翻页批量下载文件的实例详解
2021/02/02 Python
css3圆角样式分享自定义按钮样式
2013/12/27 HTML / CSS
微软俄罗斯官方网站:Microsoft俄罗斯
2016/09/18 全球购物
Auguste The Label官网:澳大利亚一家精品女装时尚品牌
2020/06/14 全球购物
马丁路德金演讲稿
2014/05/19 职场文书
条幅标语大全
2014/06/20 职场文书
父亲节活动策划方案
2014/08/24 职场文书
Vue实现下拉加载更多
2021/05/09 Vue.js
java代码实现空间切割
2022/01/18 Java/Android