drf--搜索、过滤、排序组件
drf--搜索、过滤、排序组件
过滤
DjangoFilterBackend
默认情况下 DRF generic list view 会返回整个 queryset查询结果,但通常业务只是需要其中一部分,这种情况下就需要使用 "过滤器" 来限制返回结果集。
最笨的方式是继承GenericAPIView类或使用继承了GenericAPIView的类,然后重写.get_queryset() 方法 ,首先我们看类视图中增加一个方法get_queryset
from rest_framework import generics
class ArticleViewSet(generics.ListAPIView):
queryset = Article.objects.all() # 查询结果集
serializer_class = ArticleSerializer # 序列化类
pagination_class = ArticlePagination # 自定义分页会覆盖settings全局配置的
def get_queryset(self):
queryset = Article.objects.all()
read_num = self.request.query_params.get('read_num', 0) # 获取查询字段值
if read_num:
queryset = queryset.filter(read_num__gt=int(read_num))
return queryset
通过重写get_queryset方法来达到过滤效果,这样做如果在过滤条件复杂的情况下,代码会显得过于冗余,而且有可能大部分代码一直在重复实现类似的功能,在日常操作中,我们需要获取指定条件的数据,例如对于文章,我们需要指定分类、浏览数、点赞数等。有时候我们需要按照浏览数进行排序。这些都需要我们对ArticleViewSet进行更多的拓展。
自定义过滤器django-filter模块
django-filter`库包括一个`DjangoFilterBackend`类,它支持`REST`框架的高度可定制的字段过滤。
首先安装`django-filter
pip install django-filter
然后将django_filters添加到Django的INSTALLED_APPS。
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
或者将过滤器加到单个View或ViewSet中(一般使用这种):
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
class ArticleViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = Article.objects.all() # 查询结果集
serializer_class = ArticleSerializer # 序列化类
pagination_class = ArticlePagination # 自定义分页会覆盖settings全局配置的
# 过滤器
filter_backends = (DjangoFilterBackend,)
# 如果要允许对某些字段进行过滤,可以使用filter_fields属性。
filter_fields = ('title', 'category')
# def get_queryset(self):
# queryset = Article.objects.all()
# read_num = self.request.query_params.get('read_num', 0)
#
# if read_num:
# queryset = queryset.filter(read_num__gt=int(read_num))
#
# return queryset
可以看出通过加过滤器和添加对应字段会过滤相关的,注意这里是精确匹配,字段间是且的关系,若一个为空,则按照其他的匹配,比如title=测试&category=则按照title来精确查找。
自定义过滤类
默认是按照精准匹配,若想达到模糊搜索,可以自定义过滤类,再用filter_class指定过滤集合类。
新建过滤文件filters.py
from django_filters import rest_framework
from article.models import Article
class AriticleFilter(rest_framework.FilterSet):
min_read = rest_framework.NumberFilter(field_name='read_num', lookup_expr='gte')
max_read = rest_framework.NumberFilter(field_name='read_num', lookup_expr='lte')
title = rest_framework.CharFilter(field_name='title', lookup_expr='icontains')
class Meta:
model = Article
fields = ['title', 'category', 'min_read', 'max_read']
将视图类修改
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from .filters import AriticleFilter
class ArticleViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = Article.objects.all() # 查询结果集
serializer_class = ArticleSerializer # 序列化类
pagination_class = ArticlePagination # 自定义分页会覆盖settings全局配置的
# 过滤器
filter_backends = (DjangoFilterBackend,)
# 如果要允许对某些字段进行过滤,可以使用filter_fields属性。
#filter_fields = ('title', 'category')
# 使用自定义过滤器
filter_class = AriticleFilter
搜索SearchFilter
如果要明确指定可以对哪些字段进行搜索,可以使用search_fields属性,默认为可以对serializer_class属性指定的串行器上的任何可读字段进行搜索:
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
from .filters import AriticleFilter
class ArticleViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = Article.objects.all() # 查询结果集
serializer_class = ArticleSerializer # 序列化类
pagination_class = ArticlePagination # 自定义分页会覆盖settings全局配置的
# 过滤器
filter_backends = (DjangoFilterBackend,filters.SearchFilter,)
# 如果要允许对某些字段进行过滤,可以使用filter_fields属性。
#filter_fields = ('title', 'category')
# 使用自定义过滤器
filter_class = AriticleFilter
search_fields = ('title', 'description', 'content')
默认情况下,搜索将使用不区分大小写的部分匹配。 搜索参数可以包含多个搜索项,它们应该是空格和/或逗号分隔。 如果使用多个搜索项,则仅当所有提供的条款匹配时,才会在列表中返回对象。默认情况下,搜索参数被命名为“search”,但这可能会被SEARCH_PARAM设置覆盖。
The search behavior may be restricted by prepending various characters to the search_fields.
可以通过在search_fields中加入一些字符来限制搜索行为,如下:
- '^' :以xx字符串开始搜索
- '=' :完全匹配
- '@' :全文搜索(目前只支持Django的MySQL后端)
- '$' :正则表达式搜索
如:search_fields = ('@username', '=email')
排序OrderingFilter
REST framework提供了对于排序的支持,使用REST framework提供的OrderingFilter过滤器后端即可。OrderingFilter过滤器要使用ordering_fields 属性来指明可以进行排序的字段有哪些。
from rest_framework.filters import OrderingFilter
# 过滤器,只针对当前查询过滤,所以不在settings.py中配置
filter_backends = (OrderingFilter,)
# 排序
ordering_fields = ('create_time', 'price', 'sales')
OrderingFilter 类支持对单个查询字段结果集进行排序。
默认情况下,查询参数被命名为“ordering”,但这可能会被ORDERING_PARAM设置覆盖。
可以使用ordering_fields属性明确指定可以对哪些字段执行排序,这有助于防止意外的数据泄露,例如允许用户对密码散列字段或其他敏感数据进行排序。
如果不指定ordering_fields属性,则默认为可以对serializer_class属性指定的串行器上的任何可读字段进行过滤。
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
from .filters import AriticleFilter
class ArticleViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
queryset = Article.objects.all() # 查询结果集
serializer_class = ArticleSerializer # 序列化类
pagination_class = ArticlePagination # 自定义分页会覆盖settings全局配置的
# 过滤器 过滤,搜索,排序
filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)
# 如果要允许对某些字段进行过滤,可以使用filter_fields属性。
#filter_fields = ('title', 'category')
# 使用自定义过滤器
filter_class = AriticleFilter
# 搜索
search_fields = ('title', 'description', 'content')
# 排序
ordering_fields = ('id', 'read_num')
drf--搜索、过滤、排序组件的更多相关文章
- Django(67)drf搜索过滤和排序过滤
前言 当我们需要对后台的数据进行过滤的时候,drf有两种,搜索过滤和排序过滤. 搜索过滤:比如我们想返回sex=1的,那么我们就可以从所有数据中进行筛选 排序过滤:比如我们想对价格进行升序排列,就可以 ...
- DRF之过滤排序分页异常处理
一.过滤 对于列表数据要通过字段来进行过滤,就需要添加 django-filter 模块 使用方法: # 1.注册,在app中注册 settings.py INSTALLED_APPS = [ 'dj ...
- DRF框架(八)——drf-jwt手动签发与校验、搜索过滤组件、排序过滤组件、基础分页组件
自定义drf-jwt手动签发和校验 签发token源码入口 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口,不然进不了登录页面 获取提交的username ...
- DRF内置过滤组件与排序组件结合使用
DRF内置过滤组件Filtering DRF提供了内置过滤组件Filtering,可以结合url路径的改变获取想要的数据,当然用户不可能在url访问路径中自己设置过滤条件,肯定是后端开发人员将前端页面 ...
- DRF:过滤&搜索&排序功能
过滤功能利用的是第三方包 django_filters,搜索和排序利用的是 Django DRF 提供的 filters 示例代码如下: from rest_framework import filt ...
- 46.drf过滤、搜索、排序
DRF的过滤类 drf过滤器在filters模块中,主要有四个类 BaseFilterBackend:过滤基类,留好占位方法待后续继承 SearchFilter:继承BaseFilterBackend ...
- drf框架 - 过滤组件 | 分页组件 | 过滤器插件
drf框架 接口过滤条件 群查接口各种筛选组件数据准备 models.py class Car(models.Model): name = models.CharField(max_length=16 ...
- DRF 过滤排序分页异常处理
DRF 中如何使用过滤,排序,分页,以及报错了如何处理?10分钟get了~
- #研发解决方案介绍#基于ES的搜索+筛选+排序解决方案
郑昀 基于胡耀华和王超的设计文档 最后更新于2014/12/3 关键词:ElasticSearch.Lucene.solr.搜索.facet.高可用.可伸缩.mongodb.SearchHub.商品中 ...
随机推荐
- Ubuntu 16.04/18.04 安装Shutter截图工具
在安装Shutter软件之前,先安装依赖包,下载地址: 1.libgoocanvas-common_1.0.0-1_all.deb http://launchpadli ...
- js处理日历
我们在做自动化的时候可能会遇到选择日期这种情况 这个时候我们可能就会想到直接定位不就可以了,为啥还要使用js这种东西呢? 首先,我们想一下定位:定位不仅麻烦而且还不稳定,所以这种方式我是直接就弃用了 ...
- 201871010126 王亚涛 《面向对象程序设计(Java)》第七周实验总结
---恢复内容开始--- 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com ...
- oracle 行转列~列转行(几种方法)
工作中,我们经常会碰到行转列的情况 这里我介绍几种简单的方法--行转列 1.oracle的pivot函数 原表 使用pivot函数: with temp as(select '四川省' nation ...
- 洛谷P1706 全排列问题
题目描述 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入输出格式 输入格式: n(1≤n≤9) 输出格式: 由1-n组成的所有不重复的数字序列, ...
- LG3812 「模板」线性基 线性基
问题描述 LG3812 题解 线性基是一类擅长解决异或问题的数据结构(也不算数据结构吧...就是一种玄学的东西) 对于数列 \(a\) ,它的线性基 \(d\) 为 出现 \(1\) 的最高位在第 \ ...
- nginx 403问题
错误排查 https://blog.csdn.net/onlysunnyboy/article/details/75270533 关闭 SELinux https://blog.csdn.net/ed ...
- [PHP] 关闭nginx访问favico.ico功能
关闭nginx访问favico.ico功能 nginx日志最近发生大量访问favicon.ico无法找到的错误日志,很影响服务器性能,对于一个高并发的服务器每一个错误都会影响性能 关闭访问favico ...
- Python程序设计例题
例一:蒙特卡罗方法求解 π 值 from random import random from math import sqrt from time import clock DARTS=1000 hi ...
- MySQL实战45讲学习笔记:第七讲
一.上节回顾今日计划 在上一篇文章中,我跟你介绍了 MySQL 的全局锁和表级锁,今天我们就来讲讲 MySQL的行锁. MySQL 的行锁是在引擎层由各个引擎自己实现的.但并不是所有的引擎都支持行锁, ...