DRF内置过滤组件Filtering

DRF提供了内置过滤组件Filtering,可以结合url路径的改变获取想要的数据,当然用户不可能在url访问路径中自己设置过滤条件,肯定是后端开发人员将前端页面中的与某些数据提示信息挂钩的按钮(点击事件)跟url路径中设置的检索条件绑定在一起,用户只要按需求点击相应按钮,即可获取想要的数据资源。

django-filter

一、通过django-filter增强支持:

pip install django-filter

二、在 settings.py 配置文件中增加过滤后端的设置:

# 需要将django-filter以应用的形式进行注册
INSTALLED_APPS = [
    ...
    'django_filters',
]


REST_FRAMEWORK = {
    ...
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

三、在视图中添加filter_fields属性,指定可以过滤的字段

from rest_framework.generics import ListAPIView


class StudentListView(ListAPIView):

    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    # 指定按照'age'和'sex'字段的不同值展示相应的数据
    filter_fields = ('age', 'sex')

四、url路径设置过滤字段的值

# 在所有学生信息数据中过滤出性别为男生的数据即'sex=1':
127.0.0.1:8000/four/students/?sex=1

# 在所有学生信息数据中过滤出年龄为18岁的数据即'age=18':
127.0.0.1:8000/four/students/?age=18

DRF内置排序组件OrderingFilter

在展示列表数据时,DRF提供了OrderingFilter过滤器来帮助我们将展示的所有数据按照指定字段值的大小进行排序。

一、使用方法:

在类视图中设置filter_backends 属性,使用rest_framework.filters.OrderingFilter过滤器,DRF会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序后展示。

前端可以传递的ordering参数的可选字段值需要在ordering_fields属性中指明。

示例:

from rest_framework.generics import ListAPIView
from rest_framework.filters import OrderingFilter


class StudentListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    #
    filter_backends = [OrderingFilter,]

    # 指明按照'id'和'age'字段的值的大小对数据进行排序后展示
    ordering_fields = ('id', 'age')

url路径中设置按照指定字段排序的排序方式(倒序/升序)

# 必须是ordering = 某个值

# 'ordering=-id'即表明将所有学生信息数据按照ID值的大小倒序展示
127.0.0.1:8000/four/students/?ordering=-id


# 'ordering=-age '即表明将所有学生信息数据按照年龄大小倒序展示
127.0.0.1:8000/four/students/?ordering=-age

过滤 & 排序结合使用

如果需要过滤以后再次进行排序,则需要两者结合!

示例如下:

from rest_framework.generics import ListAPIView
from students.models import Student
from .serializers import StudentModelSerializer

# 需要使用'DjangoFilterBackend'才能结合使用
from django_filters.rest_framework import DjangoFilterBackend


class Student3ListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    # 指定按照'age'和'sex'字段的不同值展示相应的数据
    filter_fields = ('age', 'sex')

    # 因为'filter_backends'是局部过滤配置,局部配置会覆盖'settinigs.py'文件中的全局配置,所以需要再次声明过滤组件核心类'DjangoFilterBackend',否则过滤功能会失效
    filter_backends = [OrderingFilter, DjangoFilterBackend]

    # 指明按照'id'和'age'字段的值的大小对数据进行排序后展示
    ordering_fields = ('id', 'age')

访问该接口时若不设置二者结合使用的条件

即:http://127.0.0.1:8080/CAPIView/students/

数据展示如下:

Students Capi

GET /CAPIView/students/

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 2,
        "name": "雄霸a",
        "sex": true,
        "age": 40,
        "class_null": "8",
        "description": "三分归元气"
    },
    {
        "id": 6,
        "name": "aaaaa",
        "sex": true,
        "age": 20,
        "class_null": "",
        "description": null
    },
    {
        "id": 7,
        "name": "1234",
        "sex": true,
        "age": 18,
        "class_null": "",
        "description": "hello666"
    },
    {
        "id": 8,
        "name": "1234",
        "sex": true,
        "age": 30,
        "class_null": "0",
        "description": "ndjskkvp"
    },
    {
        "id": 11,
        "name": "查询接口",
        "sex": false,
        "age": 23,
        "class_null": "10",
        "description": "春风十里"
    },
    {
        "id": 12,
        "name": "你好啊",
        "sex": false,
        "age": 34,
        "class_null": "1",
        "description": "就开始看看"
    },
    {
        "id": 13,
        "name": "我去啊",
        "sex": false,
        "age": 10,
        "class_null": "9",
        "description": "这个drf提供的封装好的视图子类真牛逼,我服了"
    }
]

当url路径中设置二者结合使用的条件

即:http://127.0.0.1:8080/CAPIView/students/?sex=1&ordering=-age

# 先过滤出性别为男生的数据再按照年龄倒序展示
127.0.0.1:8000/books/?sex=1&ordering=-age

数据展示如下:

Students Capi

GET /CAPIView/students/?sex=1&ordering=-age

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 2,
        "name": "雄霸a",
        "sex": true,
        "age": 40,
        "class_null": "8",
        "description": "三分归元气"
    },
    {
        "id": 8,
        "name": "1234",
        "sex": true,
        "age": 30,
        "class_null": "0",
        "description": "ndjskkvp"
    },
    {
        "id": 6,
        "name": "aaaaa",
        "sex": true,
        "age": 20,
        "class_null": "",
        "description": null
    },
    {
        "id": 7,
        "name": "1234",
        "sex": true,
        "age": 18,
        "class_null": "",
        "description": "hello666"
    }
]

当二者结合使用时,就可以先过滤后再进行排序的展示数据了,感觉挺好用的

08-14 00:51