iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 18
2

處理參數

昨日教程教授大家如何處理url上的參數,更進一步的說明就是所謂的routing,接下來的POST與PUT可就沒辦法僅是透過url傳遞,而是需要透過參數傳遞,所以今日教程旨在告訴大家如何解析請求的參數和POSTMAN 如何傳遞參數。

本文同步放置於此

新增Users

先來看看截止昨日完成的use.py應該如下圖所示,已經完成get與delete兩個方法。

from flask_restful import Resource

users = [{
    'name': 'kirai',
}]


class User (Resource):

    def get(self, name):
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        if not user:
            return {
                'message': 'username not exist!'
            }, 403
        return {
            'message': '',
            'user': user
        }

    def post(self, name):
        pass

    def put(self, name):
        pass

    def delete(self, name):
        global users
        users = [item for item in users if item['name'] != name]
        return {
            'message': 'Delete done!'
        }

不過昨日User的GET方法沒辦法確認users內容到底有多少,這裡我們新增一個Users的Resource來提交取得所有user的GET方法,相信讀者們可以獨自完成此功能,而其內容如下所示:

class Users(Resource):
    def get(self):
        return {
            'message': '',
            'users': users
        }

這裡我們在修改app.py註冊users如下所示

api.add_resource(Users, '/users/')

最後修改POSTMAN新增一個GET請求來請求users的資料如下圖所示:

相信到這邊為止提交請求可以得到下列響應:

開發POST

在完成Users這個Resource後,我們今日接續實作post。

解析請求參數

在開始之前我們先要import一個函式庫進來,因為我們需要解析請求的參數,import的內容如下:

from flask_restful import reqparse

在importreqparse這函式庫之後首先要定義欲接受請求的參數內容,定義的方式如下:

    parser = reqparse.RequestParser()
    parser.add_argument('email', required=True, help='Email is required')
    parser.add_argument('password', required=True, help='Password is required')

如此即完成參數的定義。

type

這裡因為emailpassword都是文字所以沒有特別指定其型別,若欲指定型別請使用參數type,假設參數是整數就使用type=int來將請求參數轉換成Python的int型別。

required

這個參數指的是請求參數中此參數屬於必填,入無輸入flask-restful會直接回傳錯誤。

help

這參數設定的內容指的是當請求參數驗證失敗(型別不符、未填寫)會返還的訊息。

實作POST

在定義完請求參數後接下來要開始實作post方法了,在使用reqparse之後實作post的方式就變的很簡單了,這裡就請各位讀者看看下列例子了:

    def post(self, name):
        arg = self.parser.parse_args()
        user = {
            'name': name,
            'email': arg['email'],
            'password': arg['password']
        }
        global users
        users.append(user)
        return {
            'message': 'Insert user success',
            'user': user
        }

就這樣,我們user的post方法就告一段落,接下來就先使用POSTMAN來驗證該方法實作是否有問題。

設定POSTMAN

首先先選取collection內POST的方法,如下圖所示:

接下來設定param頁籤的內容即可,這邊讀者們可以試試看透過json格式或是form的方式提交POST的request請求,如下圖所示:

JSON

FORM

相信兩個作法都能接受,因為在接受請求參數時沒有特別指定客戶端一定要傳送什麼格式的參數,若是要指定格式請見以下例子:

# Look only in the POST body
parser.add_argument('name', type=int, location='form')

# Look only in the querystring
parser.add_argument('name', type=int, location='args')

# Look only in the json
parser.add_argument('name', type=int, location='json')

# Look only in the multi location
parser.add_argument('name', type=int, location=['form', 'json'])

相信讀者們應該提交後都可以看到以下結果:

這時我們刪除email或password參數相信可以看到以下響應:

這裡透過users的GET方法顯示內容如下:

開發PUT

在開發完post要開發put相較之下就比較簡單,相信讀者應該有想法要如何處理了,這裡有個重點在於post是新增一筆資料,put是更新資料,以下就看看讀者實作的內容與筆者有什麼差別了。

    def put(self, name):
        arg = self.parser.parse_args()
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        user['email'] = arg['email']
        user['password'] = arg['password']
        return {
            'message': 'Update user success',
            'user': user
        }

如此就實作完put方法了,接下來用POSTMAN 來驗證功能是否正常即可。

驗證PUT

首先先選擇collection內的PUT方法,內容如下圖:

並且把POST的例子複製過來,結果如下圖:

JSON

FORM

相信讀者們應該會收到以下響應:

接下來透過users的GET方法顯示內容如下:

這時再修改一下name再提交PUT請求,應該會看到以下響應。

截至目前為止把目前的code都摘錄在下方:

from flask_restful import Resource, reqparse

users = [{
    'name': 'kirai',
}]


class User (Resource):

    parser = reqparse.RequestParser()
    parser.add_argument('email', required=True, help='Email is required')
    parser.add_argument('password', required=True, help='Password is required')

    def get(self, name):
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        if not user:
            return {
                'message': 'username not exist!'
            }, 403
        return {
            'message': '',
            'user': user
        }

    def post(self, name):
        arg = self.parser.parse_args()
        user = {
            'name': name,
            'email': arg['email'],
            'password': arg['password']
        }
        global users
        users.append(user)
        return {
            'message': 'Insert user success',
            'user': user
        }

    def put(self, name):
        arg = self.parser.parse_args()
        find = [item for item in users if item['name'] == name]
        if len(find) == 0:
            return {
                'message': 'username not exist!'
            }, 403
        user = find[0]
        user['email'] = arg['email']
        user['password'] = arg['password']
        return {
            'message': 'Update user success',
            'user': user
        }

    def delete(self, name):
        global users
        users = [item for item in users if item['name'] != name]
        return {
            'message': 'Delete done!'
        }


class Users(Resource):
    def get(self):
        return {
            'message': '',
            'users': users
        }

小結

今天我們已經完成user的CRUD了,而基本flask-restful也告一段落,不過有些讀者應該會發現當email或是password提交""驗證會成功,但是這不是我們想要的結果,不過明天先使用POSTMAN來設定一下測試資料讓目前的code可以隨時驗證,以便後續的維護,敬請期待。


上一篇
DAY16-搞懂Url Routing的參數處理
下一篇
DAY18-搞懂如何透過POSTMAN執行整合測試
系列文
瓶子裡裝甚麼藥,使用Flask輕輕鬆鬆打造一個RESTful API31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
timothychen
iT邦新手 5 級 ‧ 2021-07-18 23:32:41

有以下兩個問題:
1.你的一系列文章中很多的圖片都有問題,完全無法顯示。
2.arg = self.parser.parse_args()的寫法會引發flask的internal error,應該改成arg = parser.parse_args()

我要留言

立即登入留言