DRF內建過濾元件與排序元件結合使用

嗨,阿良發表於2020-08-13

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"
    }
]

當二者結合使用時,就可以先過濾後再進行排序的展示資料了,感覺挺好用的

相關文章