django-filter的详细使用
有时候前端需要各种各样的过滤查询,如果自己写多少有点麻烦和冗余。使用django-filter就可以很好的解决这个问题。
django-filter可以用在django上, 也与配合drf一起使用。
主要区别在于drf要集成的FilterSet和django的不是同一个,别的都差不多。
下面展示配合drf使用。来实现搜索过滤的功能。
安装
pip install django-filter
配置
将 'django_filters' 添加到Django的 INSTALLED_APPS 中:
INSTALLED_APPS = [
...
'django_filters',
...
]
DRF添加默认过滤后端:
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
或者将过滤器后端类添加到单个视图或视图集。
rom django_filters.rest_framework import DjangoFilterBackend
class UserListView(generics.ListAPIView):
...
filter_backends = [DjangoFilterBackend]
入门使用
如果你只是需要对模型类的字段进行等值过滤,则可以参考下面的例子,这样能够快速实现等值过滤。
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [DjangoFilterBackend]
# 使用filterset_fields属性,指定需要等值过滤的模型类字段名
filterset_fields = ['category', 'in_stock']
这将自动为给定字段创建一个 FilterSet 类,并允许您发出如下请求:
http://example.com/api/products?category=clothing&in_stock=True
如果需要实现其他条件、模糊查询等,则需要自定义FilterSet.
自定义FilterSet实现更高级的过滤规则
https://django-filter.readthedocs.io/en/stable/guide/usage.html
FilterSet类的定义的写法和DRF的序列化器几乎差不多了,因为他们都是参照django的ModelForm。
实例:
# 这里导的是django_filters.rest_framework下的filter.FilterSet,不要导错了
# from django_filters import FilterSet 这个是给django用的。
from django_filters import rest_framework as filters
# 自定义FilterSet
class BookInfoFilter(filters.FilterSet):
**# 这种叫直接声明过滤器字段,灵活性高,但如果字段比较多会相相对冗余一些..**
# **格式:**
# url中查询字符串key名 = 过滤器类型(field_name=模型类字段名, lookup_expr=过滤表达式关键词)
# lookup_expr: django的查询过滤表达式关键词,比如exact、startswith、in、gt等等...
name_like = filters.CharFilter(field_name="name", lookup_expr="icontains")
# 然后后台进行orm查询自动生成的表达式为:name__icontains执行过滤(这个就是django的过滤表达式而已)
class Meta:
model = BookInfo # 需要指定django模型类
# 如果fields 给定的是一个元组、列表,则默认自动生成的字段类只是等值过滤(没有其他过滤规则)
# 那还不如直接在视图中指定filterset_fields属性,这样更快捷。
# 所以一般我们只有实现高级过滤才会自定义FilterSet,并定义过滤器字段的查找表达式
fields = ['name', ]
# exclude 从自动过滤器生成中排除的字段。但不会禁用直接在 FilterSet 上声明的过滤器。
# exclude不能同fields同时使用。
# exclude=["is_delete"]
**# 进行name字段模糊查询时就可以使用以下url:**
# http://127.0.0.1:8000/book/viewset/?name_like=八
视图代码:
class BookInfoModelViewSet(ModelViewSet):
filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
# filterset_fields = ['readcount', 'commentcount']
# filter_class不能和filterset_fields同时指定!
# 因为filterset_fields本身就自动帮你生成一个FilterSet,实现最简单的字段等值过滤查询!
filter_class = BookInfoFilter
使用Meta.fileds来定义过滤器
原来直接定义过滤器字段,如果需要过滤的字段多则带啊吗相对冗长,如下:
class BookInfoFilter(filters.FilterSet):
name_like = filters.CharFilter(field_name="name", lookup_expr="icontains")
pub_data_year = filters.CharFilter(field_name="pub_date", lookup_expr="year__exact")
pub_data_year_gt = filters.CharFilter(field_name="pub_date", lookup_expr="year__gt")
....
class Meta:
model = BookInfo # 需要指定django模型类
fields = ['name', 'pub_date']
通过Meta.fields属性来定义过滤器
class BookInfoFilter(filters.FilterSet):
#name_like = filters.CharFilter(field_name="name", lookup_expr="icontains")
#pub_data_year = filters.CharFilter(field_name="pub_date", lookup_expr="year__exact")
#pub_data_year_gt = filters.CharFilter(field_name="pub_date", lookup_expr="year__gt")
class Meta:
model = BookInfo
# fields = ["name",]
fields = {
# 使用fileds来定义的话,URL的查询字符串会变成这样:
# ?name=xxx # 精确匹配,等值匹配extra不需要加上就可以查询。
# ?name__icontains=xxx # 模糊匹配
"name": ["exact", "icontains",],
# ?pub_data__year__gt=xxx
# ?pub_data__year__lt=xxxx
# ?pub_data__year=xxx
# ?pub_data=xxx # 日期年月日用”-“或者”/“分割,比如:2022-02-02、2023/02/02
"pub_date": ["year__gt", "year__lt", "year__exact", "exact"],
}
两种方法总结:
- 如果直接手动声明过滤器字段,则灵活较大,但是如果你需要过滤很多规则时,代码就会很多,相对冗余。好处是可以改变get查询字符串中key的名字。
- 使用fields属性通过字典的形式定义,代码比较简洁,但是无法改变get查询字符串中key的名字。
使用Filter.method来自定义过滤规则
觉得django的过滤表达式不够用?
您可以通过指定 method 来执行过滤来控制过滤器的行为。请注意,您可以访问过滤器集的属性,例如 request 。
class F(django_filters.FilterSet):
username = CharFilter(method='my_custom_filter')
class Meta:
model = User
fields = ['username']
def my_custom_filter(self, queryset, name, value):
return queryset.filter(**{
name: value,
})
更详细的用法见:https://django-filter.readthedocs.io/en/stable/ref/filters.html#filter-method
更改主查询结果集
默认情况下,FilterSet是直接模型类.objects.all()来获取所有结果集,然后再根据你指定的Filter过滤器来过滤的。
如果想改变主查询结果集,可以重写FilterSet.qs()方法.
例如,您可以将博客文章过滤为仅包含已发布的文章和登录用户拥有的文章(可能是作者的草稿文章)。
class ArticleFilter(django_filters.FilterSet):
class Meta:
model = Article
fields = [...]
@property
def qs(self):
parent = super().qs
author = getattr(self.request, 'user', None)
return parent.filter(is_published=True) \
| parent.filter(author=author)
django-filter的详细使用的更多相关文章
- Windows 10 搭建 Django 环境(详细教程)
Windows 10 搭建 Django 环境(详细教程) https://blog.csdn.net/HappyLittleMouse/article/details/81360272#1.%20P ...
- Django模版中的过滤器详细解析 Django filter大全
就象本章前面提到的一样,模板过滤器是在变量被显示前修改它的值的一个简单方法. 过滤器看起来是这样的: {{ name|lower }} 显示的内容是变量 {{ name }} 被过滤器 lower 处 ...
- Django filter中用contains 在mysql中的问题
用PYTHON ,DJANGO 做站,在通常的情况下,需要用到 orM 的查询方法,比如object.filter(tag__contains='keywords').... 在这种情况下,如果你跟踪 ...
- django filter or 多条件查询
功能:django中实现多条件查询 或关系: from django.db.models import Q return qs.filter(Q(notice_to_group__contains=' ...
- 【Python】Django filter 如何支持 or 条件过滤?
from django.db.models import Q Item.objects.filter(Q(creator=owner) | Q(moderated=False)) 代码示例: if(r ...
- Django日志记录详细的报错信息
当服务器500错误的时候,普通日志只会记录一行500的request信息,并不会记录详细的报错定位 [ERROR] 2019-06-12 15:07:03,597 "GET /api/v1/ ...
- filter的详细配置
我们已经了解了filter的基本用法,还有一些细节配置在特殊情况下起作用. 在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ includ ...
- Django视图层详细介绍
1 视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...
- PyCharm 创建指定版本的 Django (超详细图解)
最近在学习胡阳老师(the5fire)的<Django企业级开发实战>,想要使用pycharm创建django项目时,在使用virtualenv创建虚拟环境后,在pycharm内,无论如何 ...
- Python3之Django框架搭建详细步骤
安装Django 自行下载的pip,可执行如下命令: pip install django 下载python3版本可以自带pip3 ,命令如下: pip3 install django 此命令会下载d ...
随机推荐
- [htmlayout] csss! 改变值/文本
<input type="text" value="123" /> <div class="test">内容内容&l ...
- 【Azure Batch】在批处理的Task中如何让它执行多个CMD指令呢
问题描述 根据Azure Batch的入门文档(使用 Azure 门户创建 Batch 帐户并运行作业 : https://docs.azure.cn/zh-cn/batch/quick-create ...
- springboot、jvm调优(设置运行的参数)
1.工具 jdk自带的工具位置: 找到窗口->应用程序 2.问题和方式 在SpringBoot项目中,调优主要通过配置文件和配置JVM的参数的方式进行. 2.1 springboot修改配置文件 ...
- SpringBoot使用@Async注解8大坑点
前言 SpringBoot中,@Async注解可以实现异步线程调用,用法简单,体验舒适. 但是你一定碰到过异步调用不生效的情况,今天,我就列出90%的人都可能会遇到的8大坑点. 正文 1.未启用异步支 ...
- 每日一题:AJAX进度监控(附可运行源码)
1.什么是AJAX AJAX(Asynchronous JavaScript and XML)是一种用于在网页上进行异步通信的技术.它允许在不刷新整个页面的情况下,通过在后台与服务器进行数据交换来更新 ...
- 图解Spark排序算子sortBy的核心源码
原创/朱季谦 一.案例说明 以前刚开始学习Spark的时候,在练习排序算子sortBy的时候,曾发现一个有趣的现象是,在使用排序算子sortBy后直接打印的话,发现打印的结果是乱序的,并没有出现完整排 ...
- Python基础——函数的理解、函数对象、函数嵌套、闭包函数、及其应用
文章目录 函数也是变量 可以赋值 可以当做函数当做参数传给另外一个函数 可以当做函数当做另外一个函数的返回值 可以当做容器类型的一个元素 函数对象应用示范 原始版 修正版 函数嵌套 函数的嵌套调用 函 ...
- Python join拼接
import os print(os.path.join("I","love","you.")) # /XXX 代表的是绝对路径 这个变量之 ...
- 实验四报告: 熟悉Python字典、集合、字符串的使用
实验目标 本实验的主要目标是熟悉Python中字典.集合.字符串的创建和操作,包括字典的创建.访问.修改和合并,集合的创建.访问以及各种集合运算,以及字符串的创建.格式化和常用操作. 实验要求 通过编 ...
- kubernetes 概述
云原生的发展 云原生是一条最佳路径或者最佳实践.更详细的说,云原生为用户指定了一条低心智负担的.敏捷的.能够以可扩展.可复制的方式最大化地利用云的能力.发挥云的价值的最佳路径.因此,云原生其实是一套指 ...