DRF內建過濾元件與排序元件結合使用
阿新 • • 發佈:2020-08-13
# DRF內建過濾元件Filtering
DRF提供了內建過濾元件Filtering,可以結合url路徑的改變獲取想要的資料,當然使用者不可能在url訪問路徑中自己設定過濾條件,肯定是後端開發人員將前端頁面中的與某些資料提示資訊掛鉤的按鈕(點選事件)跟url路徑中設定的檢索條件繫結在一起,使用者只要按需求點選相應按鈕,即可獲取想要的資料資源。
## django-filter
**一、通過django-filter增強支援:**
```shell
pip install django-filter
```
**二、在 settings.py 配置檔案中增加過濾後端的設定:**
```python
# 需要將django-filter以應用的形式進行註冊
INSTALLED_APPS = [
...
'django_filters',
]
REST_FRAMEWORK = {
...
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
```
**三、在檢視中新增`filter_fields`屬性,指定可以過濾的欄位**
```python
from rest_framework.generics import ListAPIView
class StudentListView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentSerializer
# 指定按照'age'和'sex'欄位的不同值展示相應的資料
filter_fields = ('age', 'sex')
```
**四、url路徑設定過濾欄位的值**
```shell
# 在所有學生資訊資料中過濾出性別為男生的資料即'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`**屬性中指明。
示例:
```python
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路徑中設定按照指定欄位排序的排序方式(倒序/升序)**
```shell
# 必須是ordering = 某個值
# 'ordering=-id'即表明將所有學生資訊資料按照ID值的大小倒序展示
127.0.0.1:8000/four/students/?ordering=-id
# 'ordering=-age '即表明將所有學生資訊資料按照年齡大小倒序展示
127.0.0.1:8000/four/students/?ordering=-age
```
# 過濾 & 排序結合使用
如果需要**過濾以後再次進行排序**,則需要兩者結合!
示例如下:
```python
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/
資料展示如下:
```powershell
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
```shell
# 先過濾出性別為男生的資料再按照年齡倒序展示
127.0.0.1:8000/books/?sex=1&ordering=-age
```
資料展示如下:
```powershell
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"
}
]
```
**當二者結合使用時,就可以先過濾後再進行排序的展示資料了,感覺挺好