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.商品中 ...
随机推荐
- JMockit学习笔记
一.在eclipse下建立JMockit工程 1.下载最新版JMockit(jmockit-1.4.zip): 2.解压后的文件夹包含有:library jars, source files, sam ...
- 基于DBUtils实现数据库连接池及flask项目部署
阅读目录 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 数据库连接池原理 模式一: 模式二: 数据库连接池 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 ...
- 201871010101-陈来弟《面向对象程序设计(Java)》第八周学习总结
实验七 接口的定义与使用 第一部分:理论知识 一.接口.lambda和内部类: Comparator与comparable接口: 1.comparable接口的方法是compareTo,只有一个参数 ...
- 软件工程1916|W(福州大学)_助教博客】团队第六次作业(第9次)成绩公示
1. 作业链接: 团队作业第六次-团队Github实战训练 2. 评分准则: 本次作业评分分为两部分,一部分是博客分数(满分100分),另一部分是工程能力分数(满分30分). 博客分数计算方式: 团队 ...
- 团队冲刺---Four
今天的计划: 研究css模板. 昨天做了什么: 寻找css模板,研究界面布局. 遇到的问题: css模板,代码看不太懂,好多标签都不会用.
- NeuHub图像垃圾分类api和百度图像识别api
京东 NeuHub图像垃圾分类申请:http://neuhub.jd.com/gwtest/init/242 文档:https://aidoc.jd.com/image/garbageClassifi ...
- Burst Balloons(leetcode戳气球,困难)从指数级时间复杂度到多项式级时间复杂度的超详细优化思路(回溯到分治到动态规划)
这道题目做了两个晚上,发现解题思路的优化过程非常有代表性.文章详细说明了如何从回溯解法改造为分治解法,以及如何由分治解法过渡到动态规划解法.解法的用时从 超时 到 超过 95.6% 提交者,到超过 9 ...
- A1048 Find Coins (25 分)
一.技术总结 首先初看题目有点没读懂,题目大致意思是小明有很多个硬币不同面值的,但是现在他要到商家这里换新的面值, 且商家有一个规定,一个新的硬币必须要你两个硬币面值相加等于的来换,这一有第一个问题产 ...
- UVA10559 方块消除 Blocks 题解
设g[i][j][k]为消去区间[i,j]中的方块,只留下k个与a[i]颜色相同的方块的最大价值,f[i][j]为将[i,j]中所有方块消去的价值,转移自己yy一下即可. 为什么这样是对的?因为对于一 ...
- 8.5 NOIP模拟测试13 矩阵游戏+跳房子+优美序列
T1矩阵游戏 数学题.首先这一列这一行先乘还是后乘对最后答案没有影响.a[i][j]表示矩阵中原始的值,h[i]表示i行的累乘,l[i]表示i列的累乘.易得ans=Σa[i][j]*h[i]*l[i] ...