大家好,我們是 AI . FREE Team - 人工智慧自由團隊,這一次的鐵人賽,自由團隊將從0到1 手把手教各位讀者學會 (1)Python基礎語法 (2)Python Web 網頁開發框架 – Django (3)Python網頁爬蟲 – 周易解夢網 (4)Tensorflow AI語言模型基礎與訓練 – LSTM (5)實際部屬AI解夢模型到Web框架上。
自由團隊的成立宗旨為開發AI/新科技的學習資源,提供各領域的學習者能夠跨域學習資料科學,並透過自主學習發展協槓職涯,結合智能應用到各式領域,無論是文、法、商、管、醫領域的朋友,都可以自由的學習AI技術。
AI . FREE Team 讀者專屬福利 → Python Basics 免費學習資源
相信經過昨天的內容,大家對於 Django APP 內部程式的交互又更熟練了,相信(也希望)大家有那種自己真的在開發一個軟體的感覺。我們目前使用了 rest framework 這個套件,就是想開發一個服務(API接口服務),能依據使用者不同的 Request 有不一樣的回傳值(JSON)。在今天,我們會延伸昨日的內容,往(POST)新增、修改,和(DELETE)刪除邁進!
首先,我們來看看昨天在 demo_app/ views.py 的片段內容。
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET'])
def api_overview(request):
api_urls = {
'Schools List':'/school_list',
'School Detail View':'/school_detail/<int:id>',
'School Create':'/school_create',
'School Update':'/school_update/<int:id>',
'School Delete':'/task-delete/<int:id>'
}
return Response(api_urls)
以下段落算是複習,也算是加強概念。上方的 @api_view
,是來自安裝套件「rest_framework」的方法,我們利用了這個decorators
描述了下面的 api 準備要來接收什麼樣的 Request (i.e GET
)。所以針對上面的內容, api_overview,就是一個拿來 GET
的 API。
當 server run 起來之後,有人去GET 右邊的這個連結 (http://127.0.0.1:8000/demo_app/),將會看到下方的圖片(在 urls.py 的 urlpattern 有設定好的前提下)。
這是用來呈現我們的這個 APP 有提供什麼樣的 API 服務,有點大綱的感覺,大家可以再注意到兩件事情:
JSON
格式。在這裡的 api_overview,回傳內容是我們自己手刻的,但是在與 model 之間會發生交互的操作裡頭,我們就會需要使用到 serializer。"School List":"/school_list"
,它的存在意義就是用來列出「學派」,然後使用者(client端)想要使用的話,那就要"請求"右方的網址。http://127.0.0.1:8000/demo_app/school_list我們於上圖分別看到了,名字為 "school_create","school_update", 及 "school_delete" 的 path Object,在設計上,在這邊所對應到的 view 也告訴了我們,如果這個 path object 它被 Request 到的話,它會接著去找哪一支 view。所以我們可以想像,等等在開發 views.py 的時候,應該會要有如下圖的結構。
@api_view(['????'])
def school_create(request):
# 處理邏輯和 query 的部分
return Response(JSON Form Data)
@api_view(['????'])
def school_update(request, id):
# 處理邏輯和 query 的部分
return Response(JSON Form Data)
@api_view(['????'])
def school_delete(request, id):
# 處理邏輯和 query 的部分
return Response(...)
在方法 school_update 及 school_delete,之所以會在 input variable 使用到 id
,是因為在 path object
的 url 就有傳到這個值了。而這件事情也合理,因為我們如果想要更新東西(school_update) 或是 刪東西(school_delete),正常來說會先需要定位我們想要操作的對象,而在這邊我們就是使用到id
來定位(其實就是等等會看到對資料庫 query 的部分)。
它們的答案由上至下依序是 "POST"
, "POST"
, "DELETE"
,POST 除了在昨天提到提到可以專門用來應付寫入資料(Insert Data)的需求外,其實還可以再多做一件事情,那就是更新資料(Update Data),所以才會在這裡都用到 POST。
裡先從 view 開始寫起,先把針對「新建學派的API」寫好吧!
打開 demo_app/ views.py,並將以下內容寫入。
@api_view(['POST'])
def school_create(request):
serializer = School_Serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
因為 views.py 裡面的方法會越來越多,所以這邊就不全部列出,僅會列出部分的程式碼,大家就
選一個適合的地方放入這段程式碼即可。
通常我們想要對資料庫做類似 insert/create/update 的動作,會對應到的 Request 就會是 POST,原因在昨天稍有提及,client 端在做這個操作的時候,同時會提供一組資料(JSON形式),所以就不會是單純的 GET,而會是 POST。至於client端要如何「提供另外一組資料」,待會我們就會在成果看到了!
在這個 function 的內部都是之前沒有在 Django Shell Command 看過的內容,在這邊我們是使用到來自 rest framework 的 serializer 裡面的工具,將收到的 POST Request 中伴隨的資料轉換成資料庫可以接受的形式,也就是 Object,在這裡的例子就是把 request.data
轉換成 School Object
(i.e. serializer)。
最後的條件判斷(i.e. serializer.is_valid()
)則是在看 Request 的資料合不合法,"is_valid()" 會檢查我們傳給 API 的東西是不否有符合我們最初在 model.py 裡面的設計,如果是符合的,那它就會回傳 True
,這樣就會進到條件裡面並將資料寫入資料庫裡面。
接著我們回頭看看昨天已經寫好的 demo_app/ urls.py ,其中下面三行的部分原本是有註解掉的,但現在要用到 school create 了,所以要記得把倒數第三個path object前面的註解拿掉,變得和下面一樣喔。
urlpatterns = [
path("Confucianism/<int:id>", views.confucianism_detail, name="confucianism"),
path("Taoism/<int:id>", views.taoism_detail, name="taosim"),
path("", views.api_overview, name="api_overview"),
path("school_list", views.school_list, name="school_list"),
path("school_detail/<int:id>", views.school_detail, name="school_detail"),
# 以下為今日開發時,會使用到的內容
path("school_create", views.school_create, name="school_create"),
#path("school_update/<int:id>", views.school_update, name="school_update"),
#path("school_delete/<int:id>", views.school_delete, name="school_delete")
]
確定對應到它(views.school_create)的 url("school_create")也設定好了,所以我們已經準備齊全,可以面對 POST Request 的 API 了!
將此 Django 專案 run 起來。
$ python manage.py runserver
然後開啟瀏覽器,前往 http://127.0.0.1:8000/demo_app/school_create ,大家應該都要可以看到以下畫面。
與昨天在 school list (i.e.http://127.0.0.1:8000/demo_app/school_list) 呈現的不太一樣,在這邊多新增了一個可以輸入文字的區塊。不過當然我們在這邊,會只輸入 School (學派)規定需要提供的內容而已(想知道需要什麼內容的話,可以參考我們自己在 demo_app/ models.py 的設計喔!)。
大家可以直接把下面的內容貼到文字區塊內
{
"school_name":"AI_Free_Team",
"core_value":"Learn and become stronger",
"num_member": 999
}
並點選「POST按鈕」。
完成後,除了上方會顯示 HTTP 200 OK 等文字提示,我們也可以到昨天我們自己開發的 school_list 所對應的 url (i.e. http://127.0.0.1:8000/demo_app/school_list )看到已經多了一個學派了喔。
好,先把 demo_app/ urls.py 的最後兩個 path object 前面的註解也拿掉吧。
urlpatterns = [
path("Confucianism/<int:id>", views.confucianism_detail, name="confucianism"),
path("Taoism/<int:id>", views.taoism_detail, name="taosim"),
path("", views.api_overview, name="api_overview"),
path("school_list", views.school_list, name="school_list"),
path("school_detail/<int:id>", views.school_detail, name="school_detail"),
# 以下為今日開發時,會使用到的內容
path("school_create", views.school_create, name="school_create"),
path("school_update/<int:id>", views.school_update, name="school_update"),
path("school_delete/<int:id>", views.school_delete, name="school_delete")
]
接著,我們打開 demo_app/ views.py 一次把剩下的修改,和刪除寫完吧!
@api_view(['POST'])
def school_update(request, id):
school = School.objects.get(id=id)
serializer = School_Serializer(instance=school, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['DELETE'])
def school_delete(request, id):
school = School.objects.get(id=id)
school.delete()
return Response("Successfully Delete It.")
在這邊可以看到,想要做到這兩件事情的時候,都需要先利用我們在 Django Command Shell 有看過的方式,透過id
"定位"出預期被操作的對象,取得之後才接著做下一階段的任務。以 school_update 而言,接下來會使用 serializer 幫助修改資料;而 school_delete,就相對單純了,只需要使用 school object 的 delete() 方法,就可以了。
編輯完並且存檔之後,我們來看看修改資料會不會如期運作吧。
首先,我們用 GET 的方法看一下我們的學派分別對應到哪個 id,以下圖為例,是7。
URL: http://127.0.0.1:8000/demo_app/school_list
接著,就可以到修改對應到的URL了(注意: 最後面有 pass id=7 給school_update)
http://127.0.0.1:8000/demo_app/school_update/7
其介面和 School Create 相當一致,我們在這邊就可以把新的資料寫進去,把學派名字稍微加長了一點,多了 Ver2 字眼。
{
"school_name": "Confucianism Ver2",
"core_value": "Benevolence and courtesy between people.",
"num_member": 3952
}
接著點擊 POST 按鈕,都沒有問題的話,大家可以看到 HTTP 200 的提示,也可以回到 School_list 頁面看看是不是真的有改名喔。
最後我們來驗證 DELETE 的方法。
因為確定 id = 7 為有一個對應學派(是儒家),我們就直接到以下網址,把此學派刪掉。
點擊右上角 DELETE 按鈕就完成了,相當容易! 回到 School_list 頁面,是不是看不見剛剛已經刪除的學派了呢?
我們這兩天利用了 Django Rest Framework 實作出增刪改查API的服務,這件事情對前端的頁面
顯示其實相當重要,以臉書為例,在登入時我們輸入帳號密碼並且點選登入按鈕的動作,其實就觸發了 POST 的 Request,這個 Request 會被 臉書的 API 所接收,如果有驗證成功,才會回傳用戶的資訊(大頭貼、貼文、朋友等等),最後才再前端的部分,渲染(render)出色彩豐富的頁面。
當資料庫結構更為複雜時,API端口的設計就需要更多巧思。我們在這兩天一窺後端API的世界,希望大家有所收穫! 我們從明天開始會向前端發展,利用 bootstrap 框架撰寫網頁。大家可以先點擊操考連結中的網址認識一下 bootstrap,明天見!
自由團隊 官方網站:https://aifreeblog.herokuapp.com/
自由團隊 Github:https://github.com/AI-FREE-Team/
自由團隊 粉絲專頁:https://www.facebook.com/AI.Free.Team/
自由團隊 IG:https://www.instagram.com/aifreeteam/
自由團隊 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/
文章同步發布於:自由團隊部落格
(想看更多文章?學習更多AI知識?敬請鎖定自由團隊的頻道!)