drf之过滤器详解
Posted telecasterfanclub
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drf之过滤器详解相关的知识,希望对你有一定的参考价值。
drf之过滤详解
其实也没有多详,只是觉得这个功能可能很好用,就稍微学细一些,继续学习之后可能会被其他更好用的知识替代吧
文章部分来自 https://zhuanlan.zhihu.com/p/110060840
类似在视图中操作模型的filter,不过drf提供了过滤组件,只要简单配置,加上指定可以提供过滤的字段,就可以快速实现像在url后面用有名分组接收参数的效果
使用filter,需要先安装模块,可以在pycharm里安装也可以使用pip安装
pip install django-filter
快速配置
# setting.py
# 需要先在应用里注册,像rest_framework
INSTALLED_APPS = [
...
‘django_filters‘, # 需要注册应用,
]
# 全局配置
REST_FRAMEWORK = {
...
‘DEFAULT_FILTER_BACKENDS‘:(‘django_filters.rest_framework.DjangoFilterBackend‘,)
}
在视图中添加filter_fields属性,指定可以过滤的字段
class StudentListView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
filter_fields = (‘age‘, ‘sex‘)
# 127.0.0.1:8000/four/students/?sex=1
高级配置
可以写自己的过滤器类,在视图中导入,可以实现模糊过滤,比如包含,大于,小于等等
过滤器类和Django中表单类极其类似,写法基本一样,目的是指明过滤的时候使用哪些字段进行过滤,每个字段可以使用哪些运算。运算符的写法基本参照Django的ORM中查询的写法,比如:大于等于,小于等于用“gte”,“lte”等等
模型层以图书表为例
# 单独写一个过滤器文件,首先导入模块
from django_filters.rest_framework import FilterSet
class BookFilter(FilterSet):
class Meta:
model = Bookinfo # 模型名
fields = [‘btitle‘,‘bcomment‘] # 可以使用的过滤字段
Meta中出现的fields是指过滤条件中可以出现的字段,默认是精确判等,查询的时候可以这样用:
# bcomment=80
http://127.0.0.1:8000/book/?btitle=&bcomment=80
如果不是判等,可以自定义过滤字段进行过滤:
- 过滤器中常用的字段类型,这些类型要输模型中对应字段类型兼容
CharFilter 字符串类型
BooleanFilter 布尔类型
DateTimeFilter 日期时间类型
DateFilter 日期类型
DateRangeFilter 日期范围
TimeFilter 时间类型
NumberFilter 数值类型,对应模型中IntegerField, FloatField, DecimalField
- 参数说明:
field_name: 过滤字段名,一般应该对应模型中字段名
lookup_expr: 查询时所要进行的操作,和ORM中运算符一致
- Meta字段说明
model: 引用的模型,不是字符串
fields:指明过滤字段,可以是列表,列表中字典可以过滤,默认是判等;也可以字典,字典可以自定义操作
exclude = [‘password‘] 排除字段,不允许使用列表中字典进行过滤
自定义过滤字段:
class BookFilter(filters.FilterSet):
btitle = filters.CharFilter(field_name=‘title‘,lookup_expr=‘icontains‘)
pub_year = filters.CharFilter(field_name=‘bpub_date‘,lookup_expr=‘year‘)
pub_year__gt = filters.CharFilter(field_name=‘bpub_date‘,lookup_expr=‘year__gt‘)
bread__gt = filters.NumberFilter(field_name=‘bread‘,lookup_expr="gt")
bread__lt = filters.NumberFilter(field_name=‘bread‘,lookup_expr="lt")
class Meta:
model = Bookinfo
fields = [‘title‘,‘bread‘,‘bcomment‘]
自定义字段名可以和模型中不一致,但一定要用参数field_name指明对应模型中的字段名
日期查询
#定义按年查询,
pub_year = filters.CharFilter(field_name=‘bpub_date‘,lookup_expr=‘year‘)
# 年份应该大于某值
pub_year__gt = filters.CharFilter(field_name=‘bpub_date‘,lookup_expr=‘year__gt‘)
#年份应该小于某值
bread__lt = filters.NumberFilter(field_name=‘bread‘,lookup_expr="lt")
示例:
http://127.0.0.1:8000/book/?title=&bread=&bcomment=&btitle=&pub_year=&pub_year__gt=2014&bread__gt=&bread__lt=
查询结果:
[
{
"id": 1,
"title": "射雕英雄传",
"bpub_date": "2020-02-18",
"bread": 30,
"bcomment": 80,
"bimage": null
}
]
标题查询
# btitle查询的时候可以进行包含查询,icontains在ORM中表示不区分大小的包含
btitle = filters.CharFilter(field_name=‘btitle‘,lookup_expr=‘icontains‘)
示例:
http://127.0.0.1:8000/book/?title=&bread=&bcomment=&btitle=%E5%B0%84%E9%9B%95&pub_year=&pub_year__gt=&bread__gt=&bread__lt=
结果:
[
{
"id": 1,
"title": "射雕英雄传",
"bpub_date": "2020-02-18",
"bread": 30,
"bcomment": 80,
"bimage": null
}
]
阅读数查询
# 阅读数大于
bread__gt = filters.NumberFilter(field_name=‘bread‘,lookup_expr="gt")
# 阅读数小于
bread__lt = filters.NumberFilter(field_name=‘bread‘,lookup_expr="lt")
示例:
http://127.0.0.1:8000/book/?title=&bread=&bcomment=&btitle=&pub_year=&pub_year__gt=&bread__gt=20&bread__lt=100
结果:
[
{
"id": 1,
"title": "射雕英雄传",
"bpub_date": "2020-02-18",
"bread": 30,
"bcomment": 80,
"bimage": null
},
{
"id": 6,
"title": "连城诀",
"bpub_date": "2009-10-23",
"bread": 30,
"bcomment": 90,
"bimage": null
}
]
以上是关于drf之过滤器详解的主要内容,如果未能解决你的问题,请参考以下文章
drf之组件(认证权限排序过滤分页等)和xadmincoreapi
是否过滤 Django Rest Framework (DRF) 中的代码示例优化问题
HBase Filter 过滤器之QualifierFilter详解