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 ...
随机推荐
- 如何通过API接口获取京东的商品评论
如果您想要获取京东的商品评论,可以通过API接口来实现.这篇文章会介绍如何使用京东API接口获取商品的评论数据. 首先,您需要到京东开放平台注册成为开发者,然后创建一个应用程序.通过这个应用程序,您可 ...
- 为什么创建 Redis 集群时会自动错开主从节点?
哈喽大家好,我是咸鱼 在<一台服务器上部署 Redis 伪集群>这篇文章中,咸鱼在创建 Redis 集群时并没有明确指定哪个 Redis 实例将担任 master,哪个将担任 slave ...
- 如何在Vue3中配置国际化语言i18n
1. 安装 vue-i18n npm i vue-i18n -S 2. 创建一个i8n的配置文件 如:i18nConfig.js // 配置 vue-i18n 实现国际化语言设置 import { c ...
- 1-MySQL数据库的安装和基础语法介绍
1.MySQL是什么? MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.它是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最 ...
- Linux 安装 helm
下载helm压缩包,地址 https://github.com/helm/helm/releases/tag/v3.10.1 选择适合自己操作系统的包 上传解压安装 1 root@calico-m ...
- 用现代C++写一个python的简易型list
std::variant介绍:en.cppreference.com/w/cpp/utility/variant 通过泛型模板(仅提供了int, double, string三种类型的存储),实现了a ...
- 9.2 运用API实现线程同步
Windows 线程同步是指多个线程一同访问共享资源时,为了避免资源的并发访问导致数据的不一致或程序崩溃等问题,需要对线程的访问进行协同和控制,以保证程序的正确性和稳定性.Windows提供了多种线程 ...
- 其它——Apache-ab压力测试工具使用
文章目录 一 介绍 二 安装 2.1 windows安装 2.2 Linux安装 三 使用 四 参数介绍 一 介绍 Apache Benchmark(简称ab) 是Apache安装包中自带的压力测试工 ...
- 虹科案例|Redis企业版数据库:金融行业客户案例解读
传统银行无法提供无缝的全渠道客户体验.无法实时检测欺诈.无法获得业务洞察力.用户体验感较差.品牌声誉受损和业务损失?虹科提供的Redis企业版数据库具有低延迟.高吞吐和可用性性能,实施Redis企业版 ...
- Go 常用标准库之 fmt 介绍与基本使用
Go 常用标准库之 fmt 介绍与基本使用 目录 Go 常用标准库之 fmt 介绍与基本使用 一.介绍 二.向外输出 2.1 Print 系列 2.2 Fprint 系列 2.3 Sprint 系列 ...