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中函数传参详解
Jul 03 Python
Python做文本按行去重的实现方法
Oct 19 Python
Django实现快速分页的方法实例
Oct 22 Python
Python基于多线程操作数据库相关问题分析
Jul 11 Python
python url 参数修改方法
Dec 26 Python
Python读取stdin方法实例
May 24 Python
详解Python 中sys.stdin.readline()的用法
Sep 12 Python
python groupby 函数 as_index详解
Dec 16 Python
python实现翻译word表格小程序
Feb 27 Python
Python代码一键转Jar包及Java调用Python新姿势
Mar 10 Python
parser.add_argument中的action使用
Apr 20 Python
Python调用JavaScript代码的方法
Oct 27 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
PHP5中新增stdClass 内部保留类
2011/06/13 PHP
PHP实现提取一个图像文件并在浏览器上显示的代码
2012/10/06 PHP
php输入流php://input使用浅析
2014/09/02 PHP
PHP程序员学习使用Swoole的理由
2018/06/24 PHP
零基础学JavaScript最新动画教程+iso光盘下载
2008/01/22 Javascript
javascript div 遮罩层封锁整个页面
2009/07/10 Javascript
详解Node.js模块间共享数据库连接的方法
2016/05/24 Javascript
angularjs实现天气预报功能
2020/06/16 Javascript
vue的无缝滚动组件vue-seamless-scroll实例
2017/12/18 Javascript
在Vue中使用echarts的方法
2018/02/05 Javascript
vue.js或js实现中文A-Z排序的方法
2018/03/08 Javascript
vue-cli项目中使用公用的提示弹层tips或加载loading组件实例详解
2018/05/28 Javascript
vue中nextTick用法实例
2019/09/11 Javascript
jQuery 图片查看器插件 Viewer.js用法简单示例
2020/04/04 jQuery
JavaScript中clientWidth,offsetWidth,scrollWidth的区别
2021/01/25 Javascript
在Python的Flask框架下收发电子邮件的教程
2015/04/21 Python
Python3.2中Print函数用法实例详解
2015/05/19 Python
详解Python发送邮件实例
2016/01/10 Python
pandas的object对象转时间对象的方法
2018/04/11 Python
python反转列表的三种方式解析
2019/11/08 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
Python判断远程服务器上Excel文件是否被人打开的方法
2020/07/13 Python
香港网上花店:FlowerAdvisor香港
2019/05/30 全球购物
应届大学生自荐信格式
2013/09/21 职场文书
中专药剂专业应届毕的自我评价
2013/12/27 职场文书
办理居住证介绍信
2014/01/15 职场文书
劳动模范事迹材料
2014/01/19 职场文书
学生会干部自荐信
2014/02/04 职场文书
创建服务型党组织实施方案
2014/02/25 职场文书
政工例会汇报材料
2014/08/26 职场文书
2015教师年度考核评语
2015/03/25 职场文书
PHP实现考试倒计时功能代码
2021/04/16 PHP
Pandas数据类型之category的用法
2021/06/28 Python
redis客户端实现高可用读写分离的方式详解
2021/07/04 Redis
MYSQL 表的全面总结
2021/11/11 MySQL
一文搞清楚MySQL count(*)、count(1)、count(col)区别
2022/03/03 MySQL