iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
Modern Web

傳承D的意志~ 邁向Django的偉大航道系列 第 18

[Day 18] 實戰篇: 你一定得會的CRUD(中集)

  • 分享至 

  • xImage
  •  

嗨大家好,我是Sean!
昨天下午跟朋友去玩了LARP劇本殺,真的蠻好玩的哈哈!
推薦六個人以上的朋友團去玩,玩完以後大概還有兩個小時都在討論內容吧!

回到我們的文章,昨天我們完成了CRUD的C,也就是create的部分,以及使用了我們的postman來測試api的結果。
今天我們要繼續往下,完成CRUD的api以及他們的測試驗證。

R (Read) + filter


R,讀取的部分其實我們在之前已經有簡單的做過return全部的api了。
那麼,今天我們get特定的objects,並且搭配filter來完成。

filter

首先,我們先來介紹filetr的部分。
除了ORM本身就可以做到filter的功能外,也有另外一個好用的套件,django_filter。

第一步,自然就是安裝套件了! 別忘了先開啟虛擬環境,再輸入以下指令安裝。

pip install django-filter

第二步,將我們的django_filter加入settings.py的INSTALLED_APPS中。

INSTALLED_APPS = [
    ...,
    'rest_framework',
    'django_filters', # 新增的部分
    ...,
]

第三步,在settings.py中加入

REST_FRAMEWORK = {
  'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}

完成上述三步後,我們就可以開始引用套件,並使用它的功能了。
我們先來新增一個名為filters.py的檔案,新增在我們的app,也就是ironman的資料夾當中。

還記得我們之前寫的list api嗎?

class PeopleListAPIView(generics.ListAPIView):
    queryset = People.objects.all()
    serializer_class = PeopleSerializer 

api的內容大概長的像上圖一樣,那麼,我們該如何使用filter強化list的功能呢?

from django_filters import FilterSet, NumberFilter, CharFilter, BooleanFilter
from .models import People

class PeopleFilterSet(FilterSet):
    name = CharFilter(field_name='name', max_length=100)
    age_from = NumberFilter(field_name='age', lookup_expr='gte')
    age_to = NumberFilter(field_name='age', lookup_expr='lte')
    power = BooleanFilter(field_name='power')

    class Meta:
        model = People
        fields = ('name', 'age_from', 'age_to', 'power')

我們將People model的欄位,選出幾個可以篩選的,並將他們加入filter中。
另外,將age的filter設定為range的方式,可以更輕鬆的篩選。

再來,回到我們的view,加入我們剛剛新增的filterset就可以使用了。

from .filters import PeopleFilterSet

class PeopleListAPIView(generics.ListAPIView):
    queryset = People.objects.all()
    serializer_class = PeopleSerializer
    filter_class = PeopleFilterSet # 我們新加入的filter_class

接下來,就可以啟動程式,來看看我們加入的filter_class有甚麼效果了!

https://ithelp.ithome.com.tw/upload/images/20221003/20151096rG34ZPNGYc.png

api with filter

除了看到增加了一個filter的按鈕以外,有注意路徑的改變嗎?

我們先來說filter的按鈕能做些甚麼:
https://ithelp.ithome.com.tw/upload/images/20221003/20151096Ag5bbYBbT8.png

我們剛剛定義的filter,全部都顯示在裡面了!
等於是一個可視化的filter,可以直接在api頁面裡進行更改。
例如: 我們將20及30填入age_from, age_to的空格,然後送出執行,會得到下面的畫面。

https://ithelp.ithome.com.tw/upload/images/20221003/20151096jTd6tYqzGL.png

這麼一來就直接完成了篩選!有看到路徑也跟著改變了嗎?
原本的 http://127.0.0.1:8000/api/data/list?name=&age_from=&age_to=&power=unknown
變成了 http://127.0.0.1:8000/api/data/list?name=&age_from=20&age_to=30&power=unknown

這引導出了我們的最終目標,使用api做篩選! 讓我們用postman來展示他的效果。
貼上我們的路徑後,可以看到在params的地方自動出現了我們欄位!
https://ithelp.ithome.com.tw/upload/images/20221003/20151096shdcT4VuJP.png

在輸入params的value後,路徑也會隨之變動,這麼一來就可以依靠路徑做篩選的api了!

那麼,我們今天的文章就先到此結束!感謝大家的收看!
我是Sean,你各位海上的人,我們明天見!
https://ithelp.ithome.com.tw/upload/images/20221003/201510962999BCE1wT.jpg


上一篇
[Day 17] 實戰篇: 你一定得會的CRUD(上集)
下一篇
[Day 19] 實戰篇: 你一定得會的CRUD(下集)
系列文
傳承D的意志~ 邁向Django的偉大航道30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
max912131
iT邦新手 4 級 ‧ 2022-11-15 14:35:20

最近看到大大的此篇教學文,讓我對Django更加熟悉,
不確定是不是版本更新的影響,在ListAPIView新增filter_class的部分,
我在實際練習時,按照您的教學卻無法正確產生出篩選器,
後來Google查詢,發現目前已經更改為"filterset_class"

sean85120 iT邦新手 4 級 ‧ 2022-11-15 21:13:06 檢舉

嗨max感謝你的回覆
剛查了文件,比較新的版本的確是用filterset_class
https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html
更改完應該就可以正常使用了吧?

如果還有什麼問題都可以再留言跟我說~

【**此則訊息已被站方移除**】

我要留言

立即登入留言