有时候前端需要各种各样的过滤查询,如果自己写多少有点麻烦和冗余。使用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"],
}

两种方法总结:

  1. 如果直接手动声明过滤器字段,则灵活较大,但是如果你需要过滤很多规则时,代码就会很多,相对冗余。好处是可以改变get查询字符串中key的名字。
  2. 使用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的详细使用的更多相关文章

  1. Windows 10 搭建 Django 环境(详细教程)

    Windows 10 搭建 Django 环境(详细教程) https://blog.csdn.net/HappyLittleMouse/article/details/81360272#1.%20P ...

  2. Django模版中的过滤器详细解析 Django filter大全

    就象本章前面提到的一样,模板过滤器是在变量被显示前修改它的值的一个简单方法. 过滤器看起来是这样的: {{ name|lower }} 显示的内容是变量 {{ name }} 被过滤器 lower 处 ...

  3. Django filter中用contains 在mysql中的问题

    用PYTHON ,DJANGO 做站,在通常的情况下,需要用到 orM 的查询方法,比如object.filter(tag__contains='keywords').... 在这种情况下,如果你跟踪 ...

  4. django filter or 多条件查询

    功能:django中实现多条件查询 或关系: from django.db.models import Q return qs.filter(Q(notice_to_group__contains=' ...

  5. 【Python】Django filter 如何支持 or 条件过滤?

    from django.db.models import Q Item.objects.filter(Q(creator=owner) | Q(moderated=False)) 代码示例: if(r ...

  6. Django日志记录详细的报错信息

    当服务器500错误的时候,普通日志只会记录一行500的request信息,并不会记录详细的报错定位 [ERROR] 2019-06-12 15:07:03,597 "GET /api/v1/ ...

  7. filter的详细配置

    我们已经了解了filter的基本用法,还有一些细节配置在特殊情况下起作用. 在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ includ ...

  8. Django视图层详细介绍

    1 视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...

  9. PyCharm 创建指定版本的 Django (超详细图解)

    最近在学习胡阳老师(the5fire)的<Django企业级开发实战>,想要使用pycharm创建django项目时,在使用virtualenv创建虚拟环境后,在pycharm内,无论如何 ...

  10. Python3之Django框架搭建详细步骤

    安装Django 自行下载的pip,可执行如下命令: pip install django 下载python3版本可以自带pip3 ,命令如下: pip3 install django 此命令会下载d ...

随机推荐

  1. 数据可视化【原创】vue+arcgis+threejs 实现立体光圈闪烁效果

    本文适合对vue,arcgis4.x,threejs,ES6较熟悉的人群食用. 效果图: 素材: 主要思路: 先用arcgis externalRenderers封装了一个ExternalRender ...

  2. 大企业才用的分布式唯一Id,它比GUID好

    支持.Net Core(2.0及以上)与.Net Framework(4.5及以上) 可以部署在Docker, Windows, Linux, Mac. 分布式唯一Id,顾名思义,是指在全世界任何一台 ...

  3. 如何理解SpringBoot的Starter

    Starter是SpringBoot的四大核心功能特性之一,除此之外,SpringBoot还有自动装配,Actuator监控等特性 SpringBoot里面的这些特性,都是为了让开发者在开发基于Spr ...

  4. IDEFICS 简介: 最先进视觉语言模型的开源复现

    引言 Code Llama 是为代码类任务而生的一组最先进的.开放的 Llama 2 模型,我们很高兴能将其集成入 Hugging Face 生态系统!Code Llama 使用与 Llama 2 相 ...

  5. 1-MySQL数据库的安装和基础语法介绍

    1.MySQL是什么? MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.它是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最 ...

  6. 主动写入流对@ResponseBody注解的影响

    问题回溯 2023年Q2某日运营反馈一个问题,商品系统商家中心某批量工具模板无法下载,导致功能无法使用(因为模板是动态变化的) 商家中心报错(JSON串): {"code":-1, ...

  7. Aveva Marine VBNET 编程系列-搭建开发框架

    引用的Dll Aveva.ApplicationFramework.dll Aveva.ApplicationFramework.Presentation 菜单展示效果 创建Attribute,用于反 ...

  8. 要知其然还要知其所以然printChar

    虽然过渡与的追求细节不是好事, 但是现实社会逼迫我们不得不兼顾周全. 所以什么都是最好不仅要知其然还要知其所以然! public class printChar { public static voi ...

  9. How to install Django¶

    This document will get you up and running with Django. Install Python Being a Python Web framework, ...

  10. 数据结构与算法 | 深搜(DFS)与广搜(BFS)

    深搜(DFS)与广搜(BFS) 在查找二叉树某个节点时,如果把二叉树所有节点理理解为解空间,待找到那个节点理解为满足特定条件的解,对此解答可以抽象描述为: 在解空间中搜索满足特定条件的解,这其实就是搜 ...