8:Django-DRF-过滤器

过滤器

如名所示,过滤器就是过滤一些不想要的数据,DRF给我们提供了过滤器的模块

DRF过滤器

DRF默认是不使用过滤器的

DRF为我们提供了2个过滤器类

使用:在url添加配置中参与排序的字段

class OrderingFilter(BaseFilterBackend)	# 用于排序

使用:在url添加配置中参与搜索的字段

class searchFilter(BaseFilterBackend)	# 用于搜索

局部配置

from rest_framework.filters import OrderingFilter,SearchFilter

class view(xxx):
    # 局部配置过滤器
    filter_backends = [OrderingFilter,SearchFilter]
    # 过滤器参数:参与排序的字段
    ordering_fields = ['price','id','students']
    # 参与搜索的字段
    search_fields = ['name','brief']

全局使用:

配置文件中添加

自定义过滤器

自定义过滤器类。继承BaseFilterBackend类,实际上继不继承都可以,因为BaseFilterBackend并没有做什么实质性的事情。

必须实现filter_querytset方法,返回queryset对象
from rest_framework.filters import BaseFilterBackend


class LimitFilter(BaseFilterBackend):
    # 必须实现filter_querytset方法,返回queryset对象
    def filter_queryset(self, request, queryset, view):
        # 取出过滤条件
        limit = request.query_params.get('limit')   # 过滤参数
        try:
            return queryset[:int(limit)]
        except:
            return queryset

使用方法和DRF提供的一致

高级过滤器

安装

使用filter,需要先安装模块,可以在pycharm里安装也可以使用pip安装

pip install django-filter

settings文件配置

# 需要先在应用里注册,像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
    }
]
posted @ 2021-06-17 15:41  IT小码农!!!!  阅读(76)  评论(0)    收藏  举报